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
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/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>
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
47 struct fb_info_gen gen
;
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
;
62 #ifdef FBCON_HAS_CFB16
67 unsigned long hit_videobase
, hit_videosize
;
68 static struct fb_var_screeninfo default_var
;
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)
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
;
105 fix
->visual
= FB_VISUAL_TRUECOLOR
;
113 fix
->line_length
= par
->x
;
115 fix
->line_length
= par
->x
*2;
122 static int hitfb_decode_var(struct fb_var_screeninfo
*var
,
123 struct hitfb_par
*par
,
124 const struct fb_info
*info
)
128 par
->bpp
= var
->bits_per_pixel
;
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
));
141 var
->xres_virtual
= var
->xres
;
142 var
->yres_virtual
= var
->yres
;
145 var
->bits_per_pixel
= par
->bpp
;
147 var
->transp
.offset
= 0;
148 var
->transp
.length
= 0;
149 var
->transp
.msb_right
= 0;
154 var
->vmode
= FB_VMODE_NONINTERLACED
;
157 var
->left_margin
= 0;
158 var
->right_margin
= 0;
159 var
->upper_margin
= 0;
160 var
->lower_margin
= 0;
164 switch (var
->bits_per_pixel
) {
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;
177 case 16: /* RGB 565 */
178 var
->red
.offset
= 11;
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;
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
)
202 static void hitfb_set_par(struct hitfb_par
*par
, const struct fb_info
*info
)
204 /* Set the hardware according to '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
)
216 outw(regno
<<8, HD64461_CPTRAR
);
217 *red
= inw(HD64461_CPTRDR
)<<10;
218 *green
= inw(HD64461_CPTRDR
)<<10;
219 *blue
= inw(HD64461_CPTRDR
)<<10;
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
)
232 outw(regno
<<8, HD64461_CPTWAR
);
233 outw(red
>>10, HD64461_CPTWDR
);
234 outw(green
>>10, HD64461_CPTWDR
);
235 outw(blue
>>10, HD64461_CPTWDR
);
238 switch(current_par
.bpp
) {
239 #ifdef FBCON_HAS_CFB16
241 fbcon_cmap
.cfb16
[regno
] =
243 ((green
& 0xfc00) >> 5) |
244 ((blue
& 0xf800) >> 11);
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
)
263 static int hitfb_blank(int blank_mode
, const struct fb_info
*info
)
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
276 disp
->dispsw
= &fbcon_cfb8
;
279 #ifdef FBCON_HAS_CFB16
281 disp
->dispsw
= &fbcon_cfb16
;
282 disp
->dispsw_data
= fbcon_cmap
.cfb16
;
286 disp
->dispsw
= &fbcon_dummy
;
291 struct fbgen_hwswitch hitfb_switch
= {
305 static struct fb_ops hitfb_ops
= {
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
);
347 void hitfb_cleanup(struct fb_info
*info
)
349 unregister_framebuffer(info
);
353 int __init
hitfb_setup(char *options
)
360 int init_module(void)
365 void cleanup_module(void)