[PATCH] Q40 fbdev cleanup

From: James Simmons (jsimmons@acsu.buffalo.edu)
Date: Mon May 15 2000 - 08:01:37 EST


Hi!

  I cleaned up the Q40 fbdev driver. I don't know who the orginal author
is or his email. It compiles but I don't have this card so could someone
test this driver. Thank you.

Q: Why did they deprecate a.out support in linux?
A: Because a nasty coff is bad for your elf.

James Simmons [jsimmons@linux-fbdev.org] ____/|
fbdev/gfx developer \ o.O|
http://www.linux-fbdev.org =(_)=
http://linuxgfx.sourceforge.net U

/*
 * linux/drivers/video/q40fb.c -- Q40 frame buffer device
 *
 * (C) 2000 James Simmons
 *
 * Note I just changed this driver to the new API.
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License. See the file COPYING in the main directory of this archive for
 * more details.
 */

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/tty.h>
#include <linux/malloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>

#include <asm/uaccess.h>
#include <asm/setup.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/q40_master.h>
#include <linux/fb.h>
#include <linux/module.h>
#include <asm/pgtable.h>

#include <video/fbcon.h>
#include <video/fbcon-cfb16.h>

#define Q40_PHYS_SCREEN_ADDR 0xFE800000

static u16 pseudo_palette[17];
static struct display disp;
static struct fb_info fb_info;
static int currcon = 0;

static struct fb_fix_screeninfo q40fb_fix __initdata = {
    "Q40", (unsigned long) NULL, 1024x1024, FB_TYPE_PACKED_PIXELS, 0,
    FB_VISUAL_TRUECOLOR, 0, 0, 0, 1024*2, (unsigned long) NULL, 0, FB_ACCEL_NONE
};

static struct fb_var_screeninfo q40fb_var __initdata = {
    /* 1024x512, 16 bpp */
    1024, 512, 1024, 512, 0, 0, 16, 0,
    {6, 5, 0}, {11, 5, 0}, {0, 6, 0}, {0, 0, 0},
    0, FB_ACTIVATE_NOW, 230, 300, 0, 0, 0, 0, 0, 0, 0, 0,
    0, FB_VMODE_NONINTERLACED
};

/* frame buffer operations */
int q40fb_init(void)

static int q40fb_open(struct fb_info *info, int user);
static int q40fb_release(struct fb_info *info, int user);
static int q40fb_get_fix(struct fb_fix_screeninfo *fix, int con,
                        struct fb_info *info);
static int q40fb_get_var(struct fb_var_screeninfo *var, int con,
                        struct fb_info *info);
static int q40fb_set_var(struct fb_var_screeninfo *var, int con,
                        struct fb_info *info);
static int q40fb_get_cmap(struct fb_cmap *cmap,int kspc,int con,
                         struct fb_info *info);
static int q40fb_set_cmap(struct fb_cmap *cmap,int kspc,int con,
                         struct fb_info *info);
static int q40fb_pan_display(struct fb_var_screeninfo *var, int con,
                            struct fb_info *info);
static int q40fb_ioctl(struct inode *inode, struct file *file,
                      unsigned int cmd, unsigned long arg, int con,
                      struct fb_info *info);

static struct fb_ops q40fb_ops = {
        fb_open: q40fb_open,
        fb_release: q40fb_release,
        fb_get_fix: q40fb_get_fix,
        fb_get_var: q40fb_get_var,
        fb_set_var: q40fb_set_var,
        fb_get_cmap: q40fb_get_cmap,
        fb_set_cmap: q40fb_set_cmap,
        fb_pan_display: q40fb_pan_display,
        fb_ioctl: q40fb_ioctl
};

static int q40con_switch(int con, struct fb_info *info);
static int q40con_updatevar(int con, struct fb_info *info);
static void q40fb_blank(int blank, struct fb_info *info);

static void q40fb_set_disp(int con, struct fb_info *info);

static int q40fb_open(struct fb_info *info, int user)
{
        /*
         * Nothing, only a usage count for the moment
         */

        MOD_INC_USE_COUNT;
        return(0);
}

static int q40fb_release(struct fb_info *info, int user)
{
        MOD_DEC_USE_COUNT;
        return(0);
}

static int q40fb_get_fix(struct fb_fix_screeninfo *fix, int con,
                        struct fb_info *info)
{
        *fix = info->fix;
        return 0;
}
        
static int q40fb_get_var(struct fb_var_screeninfo *var, int con,
                        struct fb_info *info)
{
        *var = info->var;
        return 0;
}

static int q40fb_set_var(struct fb_var_screeninfo *var, int con,
                        struct fb_info *info)
{
        return -EINVAL;
}

static int q40fb_setcolreg(unsigned regno, unsigned red, unsigned green,
                             unsigned blue, unsigned transp,
                           struct fb_info *info)
{
    /*
     * Set a single color register. The values supplied have a 16 bit
     * magnitude.
     * Return != 0 for invalid regno.
     */
  
    red>>=11;
    green>>=11;
    blue>>=10;

    if (regno < 16) {
        ((u16*)(info->pseudo_palette))[regno] = ((red & 31) <<6) |
                                                ((green & 31) << 11) |
                                                 (blue & 63);
    }
    return 0;
}

static int q40fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
                         struct fb_info *info)
{
        fb_copy_cmap(&info->cmap, cmap, kspc ? 0 : 2);
        return 0;
}

static int q40fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
                         struct fb_info *info)
{
        int err = 0;

        /* current console? */
        if (con == currcon) {
                if ((err = fb_set_cmap(cmap, kspc, q40fb_setcolreg, info))) {
                        return err;
                } else {
                        fb_copy_cmap(cmap, &info->cmap, kspc ? 0 : 1);
                }
        }
        /* Always copy colormap to fb_display. */
        fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
        return err;
}

static int q40fb_pan_display(struct fb_var_screeninfo *var, int con,
                            struct fb_info *info)
{
        printk(KERN_ERR "panning not supported\n");
        return -EINVAL;
}

static int q40fb_ioctl(struct inode *inode, struct file *file,
                      unsigned int cmd, unsigned long arg, int con,
                      struct fb_info *info)
{
        return -EINVAL;
}

static void q40fb_set_disp(int con, struct fb_info *info)
{
  struct display *display;

  if (con>=0)
    display = &fb_display[con];
  else
    display = &disp;

  if (con<0) con=0;

   display->screen_base = (char *) info->fix.smem_start;
   display->visual = info->fix.visual;
   display->type = info->fix.type;
   display->type_aux = info->fix.type_aux;
   display->ypanstep = info->fix.ypanstep;
   display->ywrapstep = info->fix.ywrapstep;
   display->can_soft_blank = 0;
   display->inverse = 0;
   display->line_length = info->fix.line_length;

   display->scrollmode = SCROLL_YREDRAW;

#ifdef FBCON_HAS_CFB16
   display->dispsw = &fbcon_cfb16;
   display->dispsw_data = &pseudo_palette;
#else
   display->dispsw = &fbcon_dummy;
#endif
   fb_copy_cmap(&info->cmap, &display->cmap, 0);
}
  
int q40fb_init(void)
{
        if ( !MACH_IS_Q40)
          return -ENXIO;

        /* mapped in q40/config.c */
        q40fb_fix.smem_start = Q40_PHYS_SCREEN_ADDR;
        
        fb_info.changevar = NULL;
        fb_info.fontname[0]=0;
        fb_info.disp = &disp;
        fb_info.var = q40fb_var;
        fb_info.fix = q40fb_fix;
        strcpy(&fb_info.modename[0],fb_info.fix.id);
        fb_info.switch_con = &q40con_switch;
        fb_info.updatevar = &q40con_updatevar;
        fb_info.blank = &q40fb_blank;
        fb_info.node = -1;
        fb_info.fbops = &q40fb_ops;
        fb_info.flags = FBINFO_FLAG_DEFAULT; /* not as module for now */
        
        master_outb(3,DISPLAY_CONTROL_REG);

        memcpy(&disp.var, &fb_info.var, sizeof(struct fb_var_screeninfo));
        fb_copy_cmap(fb_default_cmap(1<<fb_info.var.bits_per_pixel),
                        &fb_info.cmap, 0);
        fb_set_cmap(&fb_info.cmap, 1, q40fb_setcolreg, &fb_info);
        q40fb_set_disp(-1, &fb_info);

        if (register_framebuffer(&fb_info) < 0) {
                printk(KERN_ERR "unable to register Q40 frame buffer\n");
                return -EINVAL;
        }

        printk(KERN_INFO "fb%d: Q40 frame buffer alive and kicking !\n",
               GET_FB_IDX(fb_info.node));
        return 0;
}
        
static int q40con_switch(int con, struct fb_info *info)
{
        struct display *prev = &fb_display[currcon];
        struct display *new = &fb_display[con];

        currcon = con;
        /* Save current colormap */
        fb_copy_cmap(&prev->fb_info->cmap, &prev->cmap, 0);
        /* Install new colormap */
        new->fb_info->fbops->fb_set_cmap(&new->cmap, 0, con, new->fb_info);
        return 0;
}

static int q40con_updatevar(int con, struct fb_info *info)
{
        return 0;
}

static void q40fb_blank(int blank, struct fb_info *info)
{
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon May 15 2000 - 21:00:25 EST