This is pre8 ...
[linux-2.6/linux-mips.git] / drivers / video / hitfb.c
blobb48b27fd3bd5deb82373fd31c4d332842356081a
1 /*
2 * $Id: hitfb.c,v 1.1 2000/06/10 21:45:40 yaegashi 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
9 * more details.
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>
18 #include <linux/mm.h>
19 #include <linux/tty.h>
20 #include <linux/malloc.h>
21 #include <linux/delay.h>
22 #include <linux/nubus.h>
23 #include <linux/init.h>
25 #include <asm/uaccess.h>
26 #include <asm/pgtable.h>
27 #include <asm/io.h>
29 #include <linux/fb.h>
31 #include <video/fbcon.h>
32 #include <video/fbcon-cfb8.h>
33 #include <video/fbcon-cfb16.h>
35 #include <asm/hd64461.h>
37 #define CONFIG_SH_LCD_VIDEOBASE CONFIG_HD64461_IOBASE+0x2000000
39 /* These are for HP Jornada 680/690.
40 It is desired that they are configurable... */
41 #define CONFIG_SH_LCD_VIDEOSIZE 1024*1024
42 #define CONFIG_SH_LCD_HORZ 640
43 #define CONFIG_SH_LCD_VERT 240
44 #define CONFIG_SH_LCD_DEFAULTBPP 16
46 struct hitfb_info {
47 struct fb_info_gen gen;
50 struct hitfb_par
52 int x, y;
53 int bpp;
56 static struct hitfb_info fb_info;
57 static struct hitfb_par current_par;
58 static int current_par_valid = 0;
59 static struct display disp;
61 static union {
62 #ifdef FBCON_HAS_CFB16
63 u16 cfb16[16];
64 #endif
65 } fbcon_cmap;
67 unsigned long hit_videobase, hit_videosize;
68 static struct fb_var_screeninfo default_var;
70 int hitfb_init(void);
71 int hitfb_setup(char*);
73 static void hitfb_set_par(struct hitfb_par *par, const struct fb_info *info);
74 static void hitfb_encode_var(struct fb_var_screeninfo *var,
75 struct hitfb_par *par,
76 const struct fb_info *info);
79 static void hitfb_detect(void)
81 struct hitfb_par par;
83 hit_videobase = CONFIG_SH_LCD_VIDEOBASE;
84 hit_videosize = CONFIG_SH_LCD_VIDEOSIZE;
86 par.x = CONFIG_SH_LCD_HORZ;
87 par.y = CONFIG_SH_LCD_VERT;
88 par.bpp = CONFIG_SH_LCD_DEFAULTBPP;
90 hitfb_set_par(&par, NULL);
91 hitfb_encode_var(&default_var, &par, NULL);
94 static int hitfb_encode_fix(struct fb_fix_screeninfo *fix,
95 struct hitfb_par *par,
96 const struct fb_info *info)
98 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
100 strcpy(fix->id, "Hitachi HD64461");
101 fix->smem_start = hit_videobase;
102 fix->smem_len = hit_videosize;
103 fix->type = FB_TYPE_PACKED_PIXELS;
104 fix->type_aux = 0;
105 fix->visual = FB_VISUAL_TRUECOLOR;
106 fix->xpanstep = 0;
107 fix->ypanstep = 0;
108 fix->ywrapstep = 0;
110 switch(par->bpp) {
111 default:
112 case 8:
113 fix->line_length = par->x;
114 case 16:
115 fix->line_length = par->x*2;
118 return 0;
122 static int hitfb_decode_var(struct fb_var_screeninfo *var,
123 struct hitfb_par *par,
124 const struct fb_info *info)
126 par->x = var->xres;
127 par->y = var->yres;
128 par->bpp = var->bits_per_pixel;
129 return 0;
133 static void hitfb_encode_var(struct fb_var_screeninfo *var,
134 struct hitfb_par *par,
135 const struct fb_info *info)
137 memset(var, 0, sizeof(*var));
139 var->xres = par->x;
140 var->yres = par->y;
141 var->xres_virtual = var->xres;
142 var->yres_virtual = var->yres;
143 var->xoffset = 0;
144 var->yoffset = 0;
145 var->bits_per_pixel = par->bpp;
146 var->grayscale = 0;
147 var->transp.offset = 0;
148 var->transp.length = 0;
149 var->transp.msb_right = 0;
150 var->nonstd = 0;
151 var->activate = 0;
152 var->height = -1;
153 var->width = -1;
154 var->vmode = FB_VMODE_NONINTERLACED;
155 var->pixclock = 0;
156 var->sync = 0;
157 var->left_margin = 0;
158 var->right_margin = 0;
159 var->upper_margin = 0;
160 var->lower_margin = 0;
161 var->hsync_len = 0;
162 var->vsync_len = 0;
164 switch (var->bits_per_pixel) {
166 case 8:
167 var->red.offset = 0;
168 var->red.length = 8;
169 var->green.offset = 0;
170 var->green.length = 8;
171 var->blue.offset = 0;
172 var->blue.length = 8;
173 var->transp.offset = 0;
174 var->transp.length = 0;
175 break;
177 case 16: /* RGB 565 */
178 var->red.offset = 11;
179 var->red.length = 5;
180 var->green.offset = 5;
181 var->green.length = 6;
182 var->blue.offset = 0;
183 var->blue.length = 5;
184 var->transp.offset = 0;
185 var->transp.length = 0;
186 break;
189 var->red.msb_right = 0;
190 var->green.msb_right = 0;
191 var->blue.msb_right = 0;
192 var->transp.msb_right = 0;
196 static void hitfb_get_par(struct hitfb_par *par, const struct fb_info *info)
198 *par = current_par;
202 static void hitfb_set_par(struct hitfb_par *par, const struct fb_info *info)
204 /* Set the hardware according to 'par'. */
205 current_par = *par;
206 current_par_valid = 1;
210 static int hitfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
211 u_int *transp, struct fb_info *info)
213 if (regno > 255)
214 return 1;
216 outw(regno<<8, HD64461_CPTRAR);
217 *red = inw(HD64461_CPTRDR)<<10;
218 *green = inw(HD64461_CPTRDR)<<10;
219 *blue = inw(HD64461_CPTRDR)<<10;
220 *transp = 0;
222 return 0;
226 static int hitfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
227 u_int transp, struct fb_info *info)
229 if (regno > 255)
230 return 1;
232 outw(regno<<8, HD64461_CPTWAR);
233 outw(red>>10, HD64461_CPTWDR);
234 outw(green>>10, HD64461_CPTWDR);
235 outw(blue>>10, HD64461_CPTWDR);
237 if(regno<16) {
238 switch(current_par.bpp) {
239 #ifdef FBCON_HAS_CFB16
240 case 16:
241 fbcon_cmap.cfb16[regno] =
242 ((red & 0xf800) ) |
243 ((green & 0xfc00) >> 5) |
244 ((blue & 0xf800) >> 11);
245 break;
246 #endif
250 return 0;
253 static int hitfb_pan_display(struct fb_var_screeninfo *var,
254 struct hitfb_par *par, const struct fb_info *info)
256 if (var->xoffset || var->yoffset)
257 return -EINVAL;
258 else
259 return 0;
263 static int hitfb_blank(int blank_mode, const struct fb_info *info)
265 return 0;
269 static void hitfb_set_disp(const void *par, struct display *disp,
270 struct fb_info_gen *info)
272 disp->screen_base = (void *)hit_videobase;
273 switch(((struct hitfb_par *)par)->bpp) {
274 #ifdef FBCON_HAS_CFB8
275 case 8:
276 disp->dispsw = &fbcon_cfb8;
277 break;
278 #endif
279 #ifdef FBCON_HAS_CFB16
280 case 16:
281 disp->dispsw = &fbcon_cfb16;
282 disp->dispsw_data = fbcon_cmap.cfb16;
283 break;
284 #endif
285 default:
286 disp->dispsw = &fbcon_dummy;
291 struct fbgen_hwswitch hitfb_switch = {
292 hitfb_detect,
293 hitfb_encode_fix,
294 hitfb_decode_var,
295 hitfb_encode_var,
296 hitfb_get_par,
297 hitfb_set_par,
298 hitfb_getcolreg,
299 hitfb_setcolreg,
300 hitfb_pan_display,
301 hitfb_blank,
302 hitfb_set_disp
305 static struct fb_ops hitfb_ops = {
306 owner: THIS_MODULE,
307 fb_get_fix: fbgen_get_fix,
308 fb_get_var: fbgen_get_var,
309 fb_set_var: fbgen_set_var,
310 fb_get_cmap: fbgen_get_cmap,
311 fb_set_cmap: fbgen_set_cmap,
312 fb_pan_display: fbgen_pan_display,
313 fb_ioctl: fbgen_ioctl,
317 int __init hitfb_init(void)
319 strcpy(fb_info.gen.info.modename, "Hitachi HD64461");
320 fb_info.gen.info.node = -1;
321 fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
322 fb_info.gen.info.fbops = &hitfb_ops;
323 fb_info.gen.info.disp = &disp;
324 fb_info.gen.info.changevar = NULL;
325 fb_info.gen.info.switch_con = &fbgen_switch;
326 fb_info.gen.info.updatevar = &fbgen_update_var;
327 fb_info.gen.info.blank = &fbgen_blank;
328 fb_info.gen.parsize = sizeof(struct hitfb_par);
329 fb_info.gen.fbhw = &hitfb_switch;
330 fb_info.gen.fbhw->detect();
332 fbgen_get_var(&disp.var, -1, &fb_info.gen.info);
333 disp.var.activate = FB_ACTIVATE_NOW;
334 fbgen_do_set_var(&disp.var, 1, &fb_info.gen);
335 fbgen_set_disp(-1, &fb_info.gen);
336 fbgen_install_cmap(0, &fb_info.gen);
338 if(register_framebuffer(&fb_info.gen.info)<0) return -EINVAL;
340 printk(KERN_INFO "fb%d: %s frame buffer device\n",
341 GET_FB_IDX(fb_info.gen.info.node), fb_info.gen.info.modename);
343 return 0;
347 void hitfb_cleanup(struct fb_info *info)
349 unregister_framebuffer(info);
353 int __init hitfb_setup(char *options)
355 return 0;
359 #ifdef MODULE
360 int init_module(void)
362 return hitfb_init();
365 void cleanup_module(void)
367 hitfb_cleanup(void);
369 #endif