/* drivers/video/s1d13xxxfb.c * * (c) 2004 Simtec Electronics * (c) 2005 Thibaut VARENE <[email protected]> * (c) 2009 Kristoffer Ericson <[email protected]> * * Driver for Epson S1D13xxx series framebuffer chips * * Adapted from * linux/drivers/video/skeletonfb.c * linux/drivers/video/epson1355fb.c * linux/drivers/video/epson/s1d13xxxfb.c (2.4 driver by Epson) * * TODO: - handle dual screen display (CRT and LCD at the same time). * - check_var(), mode change, etc. * - probably not SMP safe :) * - support all bitblt operations on all cards * * 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/module.h> #include <linux/platform_device.h> #include <linux/delay.h> #include <linux/types.h> #include <linux/errno.h> #include <linux/mm.h> #include <linux/mman.h> #include <linux/fb.h> #include <linux/spinlock_types.h> #include <linux/spinlock.h> #include <linux/slab.h> #include <linux/io.h> #include <video/s1d13xxxfb.h> #define PFX … #define BLIT … /* * set this to enable debugging on general functions */ #if 0 #define dbg … #else #define dbg(fmt, args...) … #endif /* * set this to enable debugging on 2D acceleration */ #if 0 #define dbg_blit … #else #define dbg_blit(fmt, args...) … #endif /* * we make sure only one bitblt operation is running */ static DEFINE_SPINLOCK(s1d13xxxfb_bitblt_lock); /* * list of card production ids */ static const int s1d13xxxfb_prod_ids[] = …; /* * List of card strings */ static const char *s1d13xxxfb_prod_names[] = …; /* * here we define the default struct fb_fix_screeninfo */ static const struct fb_fix_screeninfo s1d13xxxfb_fix = …; static inline u8 s1d13xxxfb_readreg(struct s1d13xxxfb_par *par, u16 regno) { … } static inline void s1d13xxxfb_writereg(struct s1d13xxxfb_par *par, u16 regno, u8 value) { … } static inline void s1d13xxxfb_runinit(struct s1d13xxxfb_par *par, const struct s1d13xxxfb_regval *initregs, const unsigned int size) { … } static inline void lcd_enable(struct s1d13xxxfb_par *par, int enable) { … } static inline void crt_enable(struct s1d13xxxfb_par *par, int enable) { … } /************************************************************* framebuffer control functions *************************************************************/ static inline void s1d13xxxfb_setup_pseudocolour(struct fb_info *info) { … } static inline void s1d13xxxfb_setup_truecolour(struct fb_info *info) { … } /** * s1d13xxxfb_set_par - Alters the hardware state. * @info: frame buffer structure * * Using the fb_var_screeninfo in fb_info we set the depth of the * framebuffer. This function alters the par AND the * fb_fix_screeninfo stored in fb_info. It doesn't not alter var in * fb_info since we are using that data. This means we depend on the * data in var inside fb_info to be supported by the hardware. * xxxfb_check_var is always called before xxxfb_set_par to ensure this. * * XXX TODO: write proper s1d13xxxfb_check_var(), without which that * function is quite useless. */ static int s1d13xxxfb_set_par(struct fb_info *info) { … } /** * s1d13xxxfb_setcolreg - sets a color register. * @regno: Which register in the CLUT we are programming * @red: The red value which can be up to 16 bits wide * @green: The green value which can be up to 16 bits wide * @blue: The blue value which can be up to 16 bits wide. * @transp: If supported the alpha value which can be up to 16 bits wide. * @info: frame buffer info structure * * Returns negative errno on error, or zero on success. */ static int s1d13xxxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info) { … } /** * s1d13xxxfb_blank - blanks the display. * @blank_mode: the blank mode we want. * @info: frame buffer structure that represents a single frame buffer * * Blank the screen if blank_mode != 0, else unblank. Return 0 if * blanking succeeded, != 0 if un-/blanking failed due to e.g. a * video mode which doesn't support it. Implements VESA suspend * and powerdown modes on hardware that supports disabling hsync/vsync: * blank_mode == 2: suspend vsync * blank_mode == 3: suspend hsync * blank_mode == 4: powerdown * * Returns negative errno on error, or zero on success. */ static int s1d13xxxfb_blank(int blank_mode, struct fb_info *info) { … } /** * s1d13xxxfb_pan_display - Pans the display. * @var: frame buffer variable screen structure * @info: frame buffer structure that represents a single frame buffer * * Pan (or wrap, depending on the `vmode' field) the display using the * `yoffset' field of the `var' structure (`xoffset' not yet supported). * If the values don't fit, return -EINVAL. * * Returns negative errno on error, or zero on success. */ static int s1d13xxxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { … } /************************************************************ functions to handle bitblt acceleration ************************************************************/ /** * bltbit_wait_bitclear - waits for change in register value * @info : frambuffer structure * @bit : value currently in register * @timeout : ... * * waits until value changes FROM bit * */ static u8 bltbit_wait_bitclear(struct fb_info *info, u8 bit, int timeout) { … } /* * s1d13xxxfb_bitblt_copyarea - accelerated copyarea function * @info : framebuffer structure * @area : fb_copyarea structure * * supports (atleast) S1D13506 * */ static void s1d13xxxfb_bitblt_copyarea(struct fb_info *info, const struct fb_copyarea *area) { … } /** * s1d13xxxfb_bitblt_solidfill - accelerated solidfill function * @info : framebuffer structure * @rect : fb_fillrect structure * * supports (atleast 13506) * **/ static void s1d13xxxfb_bitblt_solidfill(struct fb_info *info, const struct fb_fillrect *rect) { … } /* framebuffer information structures */ static const struct fb_ops s1d13xxxfb_fbops = …; static const struct fb_ops s1d13xxxfb_fbops_s1d13506 = …; static int s1d13xxxfb_width_tab[2][4] = …; /** * s1d13xxxfb_fetch_hw_state - Configure the framebuffer according to * hardware setup. * @info: frame buffer structure * * We setup the framebuffer structures according to the current * hardware setup. On some machines, the BIOS will have filled * the chip registers with such info, on others, these values will * have been written in some init procedure. In any case, the * software values needs to match the hardware ones. This is what * this function ensures. * * Note: some of the hardcoded values here might need some love to * work on various chips, and might need to no longer be hardcoded. */ static void s1d13xxxfb_fetch_hw_state(struct fb_info *info) { … } static void __s1d13xxxfb_remove(struct platform_device *pdev) { … } static void s1d13xxxfb_remove(struct platform_device *pdev) { … } static int s1d13xxxfb_probe(struct platform_device *pdev) { … } #ifdef CONFIG_PM static int s1d13xxxfb_suspend(struct platform_device *dev, pm_message_t state) { … } static int s1d13xxxfb_resume(struct platform_device *dev) { … } #endif /* CONFIG_PM */ static struct platform_driver s1d13xxxfb_driver = …; static int __init s1d13xxxfb_init(void) { … } static void __exit s1d13xxxfb_exit(void) { … } module_init(…) …; module_exit(s1d13xxxfb_exit); MODULE_LICENSE(…) …; MODULE_DESCRIPTION(…) …; MODULE_AUTHOR(…) …;