/*
* linux/drivers/video/tgafb.c -- DEC 21030 TGA frame buffer device
*
* Copyright (C) 1995 Jay Estabrook
* Copyright (C) 1997 Geert Uytterhoeven
* Copyright (C) 1999,2000 Martin Lucina, Tom Zerucha
* Copyright (C) 2002 Richard Henderson
* Copyright (C) 2006, 2007 Maciej W. Rozycki
*
* 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/bitrev.h>
#include <linux/compiler.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/selection.h>
#include <linux/string.h>
#include <linux/tc.h>
#include <asm/io.h>
#include <video/tgafb.h>
#ifdef CONFIG_TC
#define TGA_BUS_TC(dev) (dev->bus == &tc_bus_type)
#else
#define TGA_BUS_TC(dev) 0
#endif
/*
* Local functions.
*/
static int tgafb_check_var(struct fb_var_screeninfo *, struct fb_info *);
static int tgafb_set_par(struct fb_info *);
static void tgafb_set_pll(struct tga_par *, int);
static int tgafb_setcolreg(unsigned, unsigned, unsigned, unsigned,
unsigned, struct fb_info *);
static int tgafb_blank(int, struct fb_info *);
static void tgafb_init_fix(struct fb_info *);
static void tgafb_imageblit(struct fb_info *, const struct fb_image *);
static void tgafb_fillrect(struct fb_info *, const struct fb_fillrect *);
static void tgafb_copyarea(struct fb_info *, const struct fb_copyarea *);
static int tgafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
static int tgafb_register(struct device *dev);
static void tgafb_unregister(struct device *dev);
static const char *mode_option;
static const char *mode_option_pci = "640x480@60";
static const char *mode_option_tc = "1280x1024@72";
static struct pci_driver tgafb_pci_driver;
static struct tc_driver tgafb_tc_driver;
/*
* Frame buffer operations
*/
static struct fb_ops tgafb_ops = {
.owner = THIS_MODULE,
.fb_check_var = tgafb_check_var,
.fb_set_par = tgafb_set_par,
.fb_setcolreg = tgafb_setcolreg,
.fb_blank = tgafb_blank,
.fb_pan_display = tgafb_pan_display,
.fb_fillrect = tgafb_fillrect,
.fb_copyarea = tgafb_copyarea,
.fb_imageblit = tgafb_imageblit,
};
#ifdef CONFIG_PCI
/*
* PCI registration operations
*/
static int tgafb_pci_register(struct pci_dev *, const struct pci_device_id *);
static void tgafb_pci_unregister(struct pci_dev *);
static struct pci_device_id const tgafb_pci_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TGA) },
{ }
};
MODULE_DEVICE_TABLE(pci, tgafb_pci_table);
static struct pci_driver tgafb_pci_driver = {
.name = "tgafb",
.id_table = tgafb_pci_table,
.probe = tgafb_pci_register,
.remove = tgafb_pci_unregister,
};
static int tgafb_pci_register(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
return tgafb_register(&pdev->dev);
}
static void tgafb_pci_unregister(struct pci_dev *pdev)
{
tgafb_unregister(&pdev->dev);
}
#endif /* CONFIG_PCI */
#ifdef CONFIG_TC
/*
* TC registration operations
*/
static int tgafb_tc_register(struct device *);
static int tgafb_tc_unregister(struct device *);
static struct tc_device_id const tgafb_tc_table[] = {
{ "DEC ", "PMAGD-AA" },
{ "DEC ", "PMAGD " },
{ }
};
MODULE_DEVICE_TABLE(tc, tgafb_tc_table);
static struct tc_driver tgafb_tc_driver = {
.id_table = tgafb_tc_table,
.driver = {
.name = "tgafb",
.bus = &tc_bus_type,
.probe = tgafb_tc_register,
.remove = tgafb_tc_unregister,
},
};
static int tgafb_tc_register(struct device *dev)
{
int status = tgafb_register(dev);
if (!status)
get_device(dev);
return status;
}
static int tgafb_tc_unregister(struct device *dev)
{
put_device(dev);
tgafb_unregister(dev);
return 0;
}
#endif /* CONFIG_TC */
/**
* tgafb_check_var - Optional function. Validates a var passed in.
* @var: frame buffer variable screen structure
* @info: frame buffer structure that represents a single frame buffer
*/
static int
tgafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
struct tga_par *par = (struct tga_par *)info->par;
if (par->tga_type == TGA_TYPE_8PLANE) {
if (var->bits_per_pixel != 8)
|