~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/video/q40fb.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #include <linux/kernel.h>
  2 #include <linux/errno.h>
  3 #include <linux/string.h>
  4 #include <linux/mm.h>
  5 #include <linux/tty.h>
  6 #include <linux/malloc.h>
  7 #include <linux/delay.h>
  8 #include <linux/interrupt.h>
  9 
 10 #include <asm/uaccess.h>
 11 #include <asm/setup.h>
 12 #include <asm/segment.h>
 13 #include <asm/system.h>
 14 /*#include <asm/irq.h>*/
 15 #include <asm/q40_master.h>
 16 #include <linux/fb.h>
 17 #include <linux/module.h>
 18 #include <asm/pgtable.h>
 19 
 20 #include <video/fbcon.h>
 21 #include <video/fbcon-cfb16.h>
 22 
 23 #define FBIOSETSCROLLMODE   0x4611
 24 
 25 #define Q40_PHYS_SCREEN_ADDR 0xFE800000
 26 static unsigned long q40_screen_addr;
 27 
 28 static u16 fbcon_cmap_cfb16[16];
 29 
 30 /* frame buffer operations */
 31 
 32 static int q40fb_get_fix(struct fb_fix_screeninfo *fix, int con,
 33                         struct fb_info *info);
 34 static int q40fb_get_var(struct fb_var_screeninfo *var, int con,
 35                         struct fb_info *info);
 36 static int q40fb_set_var(struct fb_var_screeninfo *var, int con,
 37                         struct fb_info *info);
 38 static int q40fb_get_cmap(struct fb_cmap *cmap,int kspc,int con,
 39                          struct fb_info *info);
 40 static int q40fb_set_cmap(struct fb_cmap *cmap,int kspc,int con,
 41                          struct fb_info *info);
 42 static int q40fb_ioctl(struct inode *inode, struct file *file,
 43                       unsigned int cmd, unsigned long arg, int con,
 44                       struct fb_info *info);
 45 
 46 static int q40con_switch(int con, struct fb_info *info);
 47 static int q40con_updatevar(int con, struct fb_info *info);
 48 static void q40con_blank(int blank, struct fb_info *info);
 49 
 50 static void q40fb_set_disp(int con, struct fb_info *info);
 51 
 52 static struct display disp[MAX_NR_CONSOLES];
 53 static struct fb_info fb_info;
 54 static struct fb_ops q40fb_ops = {
 55         owner:          THIS_MODULE,
 56         fb_get_fix:     q40fb_get_fix,
 57         fb_get_var:     q40fb_get_var,
 58         fb_set_var:     q40fb_set_var,
 59         fb_get_cmap:    q40fb_get_cmap,
 60         fb_set_cmap:    q40fb_set_cmap,
 61         fb_ioctl:       q40fb_ioctl,
 62 };
 63 
 64 static int currcon=0;
 65 
 66 static char q40fb_name[]="Q40";
 67 
 68 static int q40fb_get_fix(struct fb_fix_screeninfo *fix, int con,
 69                         struct fb_info *info)
 70 {
 71         memset(fix, 0, sizeof(struct fb_fix_screeninfo));
 72 
 73         strcpy(fix->id,"Q40");
 74         fix->smem_start=q40_screen_addr;
 75         fix->smem_len=1024*1024;
 76         fix->type=FB_TYPE_PACKED_PIXELS;
 77         fix->type_aux=0;
 78         fix->visual=FB_VISUAL_TRUECOLOR;  /* good approximation so far ..*/;
 79         fix->xpanstep=0;
 80         fix->ypanstep=0;
 81         fix->ywrapstep=0;
 82         fix->line_length=1024*2;
 83 
 84         /* no mmio,accel ...*/
 85 
 86         return 0;
 87 
 88 }
 89         
 90 static int q40fb_get_var(struct fb_var_screeninfo *var, int con,
 91                         struct fb_info *info)
 92 {
 93         memset(var, 0, sizeof(struct fb_var_screeninfo));
 94 
 95         var->xres=1024;
 96         var->yres=512;
 97         var->xres_virtual=1024;
 98         var->yres_virtual=512;
 99         var->xoffset=0;
100         var->yoffset=0;
101         var->bits_per_pixel=16;
102         var->grayscale=0;
103         var->nonstd=0;
104         var->activate=FB_ACTIVATE_NOW;
105         var->height=230;     /* approx for my 17" monitor, more important */
106         var->width=300;      /* than the absolute values is the unusual aspect ratio*/
107 
108         var->red.offset=6; /*6*/
109         var->red.length=5;
110         var->green.offset=11; /*11*/
111         var->green.length=5;
112         var->blue.offset=0;
113         var->blue.length=6;
114         var->transp.length=0;
115 
116         var->pixclock=0;
117         var->left_margin=0;
118         var->right_margin=0;
119         var->hsync_len=0;
120         var->vsync_len=0;
121         var->sync=0;
122         var->vmode=FB_VMODE_NONINTERLACED;
123 
124         return 0;
125 
126 }
127 
128 static int q40fb_set_var(struct fb_var_screeninfo *var, int con,
129                         struct fb_info *info)
130 {
131         if(var->xres!=1024) 
132                 return -EINVAL;
133         if(var->yres!=512)
134                 return -EINVAL;
135         if(var->xres_virtual!=1024)
136                 return -EINVAL;
137         if(var->yres_virtual!=512)
138                 return -EINVAL;
139         if(var->xoffset!=0)
140                 return -EINVAL;
141         if(var->yoffset!=0)
142                 return -EINVAL;
143         if(var->bits_per_pixel!=16)
144                 return -EINVAL;
145         if(var->grayscale!=0)
146                 return -EINVAL;
147         if(var->nonstd!=0)
148                 return -EINVAL;
149         if(var->activate!=FB_ACTIVATE_NOW)
150                 return -EINVAL;
151         if(var->pixclock!=0)
152                 return -EINVAL;
153         if(var->left_margin!=0)
154                 return -EINVAL;
155         if(var->right_margin!=0)
156                 return -EINVAL;
157         if(var->hsync_len!=0)
158                 return -EINVAL;
159         if(var->vsync_len!=0)
160                 return -EINVAL;
161         if(var->sync!=0)
162                 return -EINVAL;
163         if(var->vmode!=FB_VMODE_NONINTERLACED)
164                 return -EINVAL;
165 
166         return 0;
167 
168 }
169 
170 static int q40_getcolreg(unsigned regno, unsigned *red, unsigned *green,
171                          unsigned *blue, unsigned *transp,
172                          struct fb_info *info)
173 {
174     /*
175      *  Read a single color register and split it into colors/transparent.
176      *  The return values must have a 16 bit magnitude.
177      *  Return != 0 for invalid regno.
178      */
179     if (regno>=16) return 1;
180 
181     *transp=0;
182     *green = ((fbcon_cmap_cfb16[regno]>>11) & 31)<<11;
183     *red   = ((fbcon_cmap_cfb16[regno]>>6) & 31)<<11;
184     *blue  = ((fbcon_cmap_cfb16[regno]) & 63)<<10;
185 
186     return 0;
187 }
188 
189 static int q40_setcolreg(unsigned regno, unsigned red, unsigned green,
190                          unsigned blue, unsigned transp,
191                          const struct fb_info *info)
192 {
193     /*
194      *  Set a single color register. The values supplied have a 16 bit
195      *  magnitude.
196      *  Return != 0 for invalid regno.
197      */
198   
199   red>>=11;
200   green>>=11;
201   blue>>=10;
202 
203     if (regno < 16) {
204       fbcon_cmap_cfb16[regno] = ((red & 31) <<6) |
205                                  ((green & 31) << 11) |
206                                  (blue & 63);
207     }
208     return 0;
209 }
210 
211 static int q40fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
212                          struct fb_info *info)
213 {
214 #if 1
215         if (con == currcon) /* current console? */
216                 return fb_get_cmap(cmap, kspc, q40_getcolreg, info);
217         else if (fb_display[con].cmap.len) /* non default colormap? */
218                 fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
219         else
220                 fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
221                              cmap, kspc ? 0 : 2);
222         return 0;
223 #else
224         printk(KERN_ERR "get cmap not supported\n");
225 
226         return -EINVAL;
227 #endif
228 }
229 
230 static int q40fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
231                          struct fb_info *info)
232 {
233 #if 1
234         int err;
235 
236         if (!fb_display[con].cmap.len) {        /* no colormap allocated? */
237                 if ((err = fb_alloc_cmap(&fb_display[con].cmap,
238                                          1<<fb_display[con].var.bits_per_pixel,
239                                          0)))
240                         return err;
241         }
242         if (con == currcon)                     /* current console? */
243                 return fb_set_cmap(cmap, kspc, q40_setcolreg, info);
244         else
245                 fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
246         return 0;
247 #else
248         printk(KERN_ERR "set cmap not supported\n");
249 
250         return -EINVAL;
251 #endif
252 }
253 
254 static int q40fb_ioctl(struct inode *inode, struct file *file,
255                       unsigned int cmd, unsigned long arg, int con,
256                       struct fb_info *info)
257 {
258 #if 0
259         unsigned long i;
260         struct display *display;
261 
262         if (con>=0)
263           display = &fb_display[con];
264         else
265           display = &disp[0];
266 
267         if (cmd == FBIOSETSCROLLMODE)
268           {
269             i = verify_area(VERIFY_READ, (void *)arg, sizeof(unsigned long));
270             if (!i) 
271               {
272                 copy_from_user(&i, (void *)arg, sizeof(unsigned long));
273                 display->scrollmode = i;
274               }
275             q40_updatescrollmode(display);
276             return i;
277           }
278 #endif
279         return -EINVAL;
280 }
281 
282 static void q40fb_set_disp(int con, struct fb_info *info)
283 {
284   struct fb_fix_screeninfo fix;
285   struct display *display;
286 
287   q40fb_get_fix(&fix, con, info);
288 
289   if (con>=0)
290     display = &fb_display[con];
291   else  
292     display = &disp[0];
293 
294   if (con<0) con=0;
295 
296    display->screen_base = fix.smem_start;
297    display->visual = fix.visual;
298    display->type = fix.type;
299    display->type_aux = fix.type_aux;
300    display->ypanstep = fix.ypanstep;
301    display->ywrapstep = fix.ywrapstep;
302    display->can_soft_blank = 0;
303    display->inverse = 0;
304    display->line_length = fix.line_length;
305 
306    display->scrollmode = SCROLL_YREDRAW;
307 
308 #ifdef FBCON_HAS_CFB16
309    display->dispsw = &fbcon_cfb16;
310    disp->dispsw_data = fbcon_cmap_cfb16;
311 #else
312    display->dispsw = &fbcon_dummy;
313 #endif
314 }
315   
316 int __init q40fb_init(void)
317 {
318 
319         if ( !MACH_IS_Q40)
320           return -ENXIO;
321 #if 0
322         q40_screen_addr = kernel_map(Q40_PHYS_SCREEN_ADDR, 1024*1024,
323                                            KERNELMAP_NO_COPYBACK, NULL);
324 #else
325         q40_screen_addr = Q40_PHYS_SCREEN_ADDR; /* mapped in q40/config.c */
326 #endif
327 
328         fb_info.changevar=NULL;
329         strcpy(&fb_info.modename[0],q40fb_name);
330         fb_info.fontname[0]=0;
331         fb_info.disp=disp;
332         fb_info.switch_con=&q40con_switch;
333         fb_info.updatevar=&q40con_updatevar;
334         fb_info.blank=&q40con_blank;    
335         fb_info.node = -1;
336         fb_info.fbops = &q40fb_ops;
337         fb_info.flags = FBINFO_FLAG_DEFAULT;  /* not as module for now */
338         
339         master_outb(3,DISPLAY_CONTROL_REG);
340 
341         q40fb_get_var(&disp[0].var, 0, &fb_info);
342         q40fb_set_disp(-1, &fb_info);
343 
344         if (register_framebuffer(&fb_info) < 0) {
345                 printk(KERN_ERR "unable to register Q40 frame buffer\n");
346                 return -EINVAL;
347         }
348 
349         printk(KERN_INFO "fb%d: Q40 frame buffer alive and kicking !\n",
350                GET_FB_IDX(fb_info.node));
351         return 0;
352 }       
353 
354         
355 static int q40con_switch(int con, struct fb_info *info)
356 { 
357         currcon=con;
358         
359         return 0;
360 
361 }
362 
363 static int q40con_updatevar(int con, struct fb_info *info)
364 {
365         return 0;
366 }
367 
368 static void q40con_blank(int blank, struct fb_info *info)
369 {
370 }
371 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.