📄 s1d13xxxfb.c~
字号:
//-----------------------------------------------------------------------------// // linux/drivers/video/s1d13xxxfb.c -- frame buffer driver for Epson S1D13xxx//// Copyright(c) 2000, 2001 Epson Research and Development, Inc. // All rights reserved.////---------------------------------------------------------------------------- //// This driver supports one of the following Epson CRT/TV/LCD controllers://// S1D13504// S1D13505// S1D13506// S1D13704// S1D13705// S1D13706// S1D13806// S1D13A03// S1D13A04// S1D13A05//// The intended platforms for this driver are embedded systems, where memory // resources are very limited, hence there are virtually no run-time checks// present in the driver code. The objective is to keep the footprint as small// as possible. For example, we do not keep a mirror image of palette. The con-// sequence being that writing a palette entry and then reading it back may// result in different value, as most of the supported chips don't support // full 8 bits per primary colors (red,green,blue). // This does not seem to affect the driver much.//// During the driver compilation, the following hash-defines are being used to // identify the target Epson controller://// CONFIG_FBCON_EPSON_S1D13504 // CONFIG_FBCON_EPSON_S1D13505 // CONFIG_FBCON_EPSON_S1D13506 // CONFIG_FBCON_EPSON_S1D13704 // CONFIG_FBCON_EPSON_S1D13705 // CONFIG_FBCON_EPSON_S1D13706 // CONFIG_FBCON_EPSON_S1D13806// CONFIG_FBCON_EPSON_S1D13A03// CONFIG_FBCON_EPSON_S1D13A04// CONFIG_FBCON_EPSON_S1D13A05//// Most of the chips were tested using Epson evaluation boards. The boards come// basically in two flavors: ISA bus adapters or PCI adapters. To support the// PCI adapters, make sure to specify PCI bridge adapter during configuration.// This will generate the following hash-define://// CONFIG_FBCON_EPSON_PCI// // The driver will be build for one colordepth only. It must be one of the // following: 4Bpp,8Bpp or 16Bpp. This is selected during the configuration // phase and generates one of the hash-defines: //// FBCON_HAS_CFB4// FBCON_HAS_CFB8// FBCON_HAS_CFB16//// Additionally,there are some hash-defines specifying the display geometry// and LUT register accesses. These are chip dependent and are located in // corresponding S1D13XXX header files. ////-----------------------------------------------------------------------------#include <linux/module.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/tty.h>#include <linux/slab.h>#include <linux/delay.h>#include <linux/fb.h>#include <linux/init.h>#include <linux/pci.h>#include <video/fbcon.h> #include <video/fbcon-cfb4.h>#include <video/fbcon-cfb8.h>#include <video/fbcon-cfb16.h>#include <asm/arch/ics1523.h>#include <asm/arch/AT91RM9200_TWI.h>#include <asm/arch/AT91RM9200.h>#include <asm/arch/AT91RM9200_SPI.h>//----------------------------------------------------------------------------- //// Sanity checks// //----------------------------------------------------------------------------- // Check if at least one supported colordepth was configured#if !defined (FBCON_HAS_CFB4) && !defined (FBCON_HAS_CFB8) && \ !defined (FBCON_HAS_CFB16) #error No colordepth specified#endif// S1D13504 supports only 4Bpp,16Bpp, no PCI bridge card.#ifdef CONFIG_FBCON_EPSON_S1D13504 #if defined (FBCON_HAS_CFB8) || \ defined (CONFIG_FBCON_EPSON_PCI) || !defined(FBCON_HAS_CFB16) #error Invalid configuration! #endif #if defined (FBCON_HAS_CFB4) && defined (FBCON_HAS_CFB16) #error More than one colordepth specified #endif#include "s1d13504.h"#endif// S1D13505 supports 8Bpp,16Bpp, no PCI bridge card.#ifdef CONFIG_FBCON_EPSON_S1D13505 #if defined (FBCON_HAS_CFB4) || defined (CONFIG_FBCON_EPSON_PCI) #error Invalid configuration! #endif #if defined (FBCON_HAS_CFB8) && defined (FBCON_HAS_CFB16) #error More than one colordepth specified #endif#include "s1d13505.h"#endif// S1D13506 supports 4Bpp,8Bpp,16Bpp#ifdef CONFIG_FBCON_EPSON_S1D13506 #if defined (FBCON_HAS_CFB4) && defined (FBCON_HAS_CFB16) #error More than one colordepth specified #endif #if defined (FBCON_HAS_CFB4) && defined (FBCON_HAS_CFB8) #error More than one colordepth specified #endif #if defined (FBCON_HAS_CFB8) && defined (FBCON_HAS_CFB16) #error More than one colordepth specified #endif#include "s1d13506.h"#endif// S1D13704 supports 4Bpp, no PCI bridge card#ifdef CONFIG_FBCON_EPSON_S1D13704 #if defined (FBCON_HAS_CFB8) || defined (FBCON_HAS_CFB16) || \ defined (CONFIG_FBCON_EPSON_PCI) #error Invalid configuration! #endif#include "s1d13704.h"#endif// S1D13705 supports 4Bpp, 8Bpp. No PCI bridge card#ifdef CONFIG_FBCON_EPSON_S1D13705 #if defined (FBCON_HAS_CFB16) || defined (CONFIG_FBCON_EPSON_PCI) #error Invalid configuration! #endif #if defined (FBCON_HAS_CFB4) && defined (FBCON_HAS_CFB8) #error More than one colordepth specified #endif#include "s1d13705.h"#endif// S1D13706 supports 4Bpp, 8Bpp, 16Bpp#ifdef CONFIG_FBCON_EPSON_S1D13706 #if defined (FBCON_HAS_CFB4) && defined (FBCON_HAS_CFB8) #error More than one colordepth specified #endif #if defined (FBCON_HAS_CFB4) && defined (FBCON_HAS_CFB16) #error More than one colordepth specified #endif #if defined (FBCON_HAS_CFB8) && defined (FBCON_HAS_CFB16) #error More than one colordepth specified #endif#include "s1d13706.h"#endif// S1D13806 supports 4Bpp,8Bpp,16Bpp#ifdef CONFIG_FBCON_EPSON_S1D13806_AT91RM9200DK #if defined (FBCON_HAS_CFB4) && defined (FBCON_HAS_CFB8) #error More than one colordepth specified #endif #if defined (FBCON_HAS_CFB4) && defined (FBCON_HAS_CFB16) #error More than one colordepth specified #endif #if defined (FBCON_HAS_CFB8) && defined (FBCON_HAS_CFB16) #error More than one colordepth specified #endif#include "s1d13806.h"#endif// S1D13A0X supports 4Bpp, 8Bpp, 16Bpp#ifdef CONFIG_FBCON_EPSON_S1D13A0X #if defined (FBCON_HAS_CFB4) && defined (FBCON_HAS_CFB8) #error More than one colordepth specified #endif #if defined (FBCON_HAS_CFB4) && defined (FBCON_HAS_CFB16) #error More than one colordepth specified #endif #if defined (FBCON_HAS_CFB8) && defined (FBCON_HAS_CFB16) #error More than one colordepth specified #endif#include "s1d13a0x.h"S1D_INSTANTIATE_REGISTERS(static,aS1DRegs);#endif// Now that the include file has been successfully read in, make sure // it's for the right colordepth#if (defined (FBCON_HAS_CFB4) && (S1D_DISPLAY_BPP != 4)) || \ (!defined(FBCON_HAS_CFB4) && (S1D_DISPLAY_BPP == 4)) #error Include file colordepth mismatch!#endif#if (defined (FBCON_HAS_CFB8) && (S1D_DISPLAY_BPP != 8)) || \ (!defined(FBCON_HAS_CFB8) && (S1D_DISPLAY_BPP == 8)) #error Include file colordepth mismatch!#endif#if (defined (FBCON_HAS_CFB16) && (S1D_DISPLAY_BPP != 16)) || \ (!defined(FBCON_HAS_CFB16) && (S1D_DISPLAY_BPP == 16)) #error Include file colordepth mismatch!#endif//----------------------------------------------------------------------------- //// Local Definitions// //----------------------------------------------------------------------------- typedef struct { struct fb_info_gen gen; unsigned char *VmemAddr; volatile unsigned char *RegAddr; #ifdef CONFIG_FBCON_EPSON_PCI u32 PhysAddr;#endif#ifdef FBCON_HAS_CFB16 u16 cfb16[16];#endif }FB_INFO_S1D13xxx; //-----------------------------------------------------------------------------//// Function Prototypes // //-----------------------------------------------------------------------------int __init s1d13xxxfb_setup(char *options, int *ints) ;int __init s1d13xxxfb_init(char*) ;static void s1d13xxx_detect(void); static int s1d13xxx_encode_fix(struct fb_fix_screeninfo *fix, const void *par, struct fb_info_gen *info); static int s1d13xxx_decode_var(const struct fb_var_screeninfo *var, void *par, struct fb_info_gen *info); static int s1d13xxx_encode_var(struct fb_var_screeninfo *var, const void *par, struct fb_info_gen *info); static void s1d13xxx_get_par(void *par, struct fb_info_gen *info); static void s1d13xxx_set_par(const void *par, struct fb_info_gen *info); static int s1d13xxx_getcolreg(unsigned regno, unsigned *red, unsigned *green, unsigned *blue, unsigned *transp, struct fb_info *info); static int s1d13xxx_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info); static int s1d13xxx_pan_display(const struct fb_var_screeninfo *var, struct fb_info_gen *info); static int s1d13xxx_blank(int blank_mode, struct fb_info_gen *info); static void s1d13xxx_set_disp(const void *par, struct display *disp, struct fb_info_gen *info);static ints1d13xxx_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma);//----------------------------------------------------------------------------- //// Local globals// //----------------------------------------------------------------------------- static struct fb_ops s1d13xxxfb_ops = { owner: THIS_MODULE, // fb_open: s1d13xxxfb_open, fb_get_fix: fbgen_get_fix, fb_get_var: fbgen_get_var, fb_set_var: fbgen_set_var, fb_get_cmap: fbgen_get_cmap, fb_set_cmap: fbgen_set_cmap, fb_mmap: s1d13xxx_mmap, };/* * In most cases the `generic' routines (fbgen_*) should be satisfactory. * However, you're free to fill in your own replacements. */static struct fbgen_hwswitch s1d13xxx_hwswitch = { s1d13xxx_detect, s1d13xxx_encode_fix, s1d13xxx_decode_var, s1d13xxx_encode_var, s1d13xxx_get_par, s1d13xxx_set_par, s1d13xxx_getcolreg, s1d13xxx_setcolreg, s1d13xxx_pan_display, s1d13xxx_blank, s1d13xxx_set_disp }; static FB_INFO_S1D13xxx fb_info; static struct display disp; static char __initdata default_fontname[40] = { 0 }; //----------------------------------------------------------------------------- // // This function should detect the current video mode settings and store // it as the default video mode // //----------------------------------------------------------------------------- static void s1d13xxx_detect(void) { } /* * Note that we are entered with the kernel locked. */static ints1d13xxx_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma){ unsigned long off, start; u32 len; off = vma->vm_pgoff << PAGE_SHIFT;#ifdef CONFIG_FBCON_EPSON_PCI start = fb_info.PhysAddr;#else start = S1D_PHYSICAL_VMEM_ADDR;#endif len = PAGE_ALIGN(start & ~PAGE_MASK) + S1D_PHYSICAL_VMEM_ADDR; start &= PAGE_MASK; if ((vma->vm_end - vma->vm_start + off) > len) return -EINVAL; off += start; vma->vm_pgoff = off >> PAGE_SHIFT; /* This is an IO map - tell maydump to skip this VMA */ vma->vm_flags |= VM_IO;#ifdef CONFIG_CPU_32 pgprot_val(vma->vm_page_prot) &= ~L_PTE_CACHEABLE;#endif /* * Don't alter the page protection flags; we want to keep the area * cached for better performance. This does mean that we may miss * some updates to the screen occasionally, but process switches * should cause the caches and buffers to be flushed often enough. */ if (io_remap_page_range(vma->vm_start, off, vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; return 0;}//----------------------------------------------------------------------------- // // This function should fill in the 'fix' structure based on the values // in the `par' structure. // //----------------------------------------------------------------------------- static int s1d13xxx_encode_fix(struct fb_fix_screeninfo *fix, const void *par, struct fb_info_gen *info) { memset(fix, 0, sizeof(struct fb_fix_screeninfo)); strcpy(fix->id, fb_info.gen.info.modename); fix->type = FB_TYPE_PACKED_PIXELS; /* see FB_TYPE_* in fb.h */ fix->type_aux = 0; /* Interleave for interleaved Planes */ /* set fix->line_length to the length of the line in bytes */ fix->line_length = S1D_DISPLAY_SCANLINE_BYTES; #ifdef FBCON_HAS_CFB4 fix->visual = FB_VISUAL_STATIC_PSEUDOCOLOR;#endif#ifdef FBCON_HAS_CFB8 fix->visual = FB_VISUAL_PSEUDOCOLOR;#endif#ifdef FBCON_HAS_CFB16 fix->visual = FB_VISUAL_DIRECTCOLOR;#endif /* Start and length of Memory Mapped I/O */ fix->mmio_start = S1D_PHYSICAL_REG_ADDR; fix->mmio_len = S1D_PHYSICAL_REG_SIZE; /* Start and length of frame buffer mem */ fix->smem_start = S1D_PHYSICAL_VMEM_ADDR; fix->smem_len = S1D_PHYSICAL_VMEM_SIZE; fix->xpanstep = fix->ypanstep = fix->ywrapstep = 0; fix->accel = FB_ACCEL_NONE; return 0; } //----------------------------------------------------------------------------- // // Get the video params out of 'var'. If a value doesn't fit, round it up, // if it's too big, return -EINVAL. // // Suggestion: Round up in the following order: bits_per_pixel, xres, // yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale, // bitfields, horizontal timing, vertical timing. // //----------------------------------------------------------------------------- static int s1d13xxx_decode_var(const struct fb_var_screeninfo *var, void *fb_par, struct fb_info_gen *info) { return 0; } //----------------------------------------------------------------------------- //// Fill the 'var' structure based on the values in 'par' and maybe other
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -