Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2)  * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *  Modified to new api Jan 2001 by James Simmons (jsimmons@transvirtual.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *  Created 28 Dec 1997 by Geert Uytterhoeven
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  *  I have started rewriting this driver as a example of the upcoming new API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  *  The primary goal is to remove the console code from fbdev and place it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  *  into fbcon.c. This reduces the code and makes writing a new fbdev driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  *  easy since the author doesn't need to worry about console internals. It
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  *  also allows the ability to run fbdev without a console/tty system on top 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  *  of it. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  *  First the roles of struct fb_info and struct display have changed. Struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  *  display will go away. The way the new framebuffer console code will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)  *  work is that it will act to translate data about the tty/console in 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)  *  struct vc_data to data in a device independent way in struct fb_info. Then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20)  *  various functions in struct fb_ops will be called to store the device 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21)  *  dependent state in the par field in struct fb_info and to change the 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22)  *  hardware to that state. This allows a very clean separation of the fbdev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23)  *  layer from the console layer. It also allows one to use fbdev on its own
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24)  *  which is a bounus for embedded devices. The reason this approach works is  
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25)  *  for each framebuffer device when used as a tty/console device is allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26)  *  a set of virtual terminals to it. Only one virtual terminal can be active 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27)  *  per framebuffer device. We already have all the data we need in struct 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28)  *  vc_data so why store a bunch of colormaps and other fbdev specific data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29)  *  per virtual terminal. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31)  *  As you can see doing this makes the con parameter pretty much useless
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32)  *  for struct fb_ops functions, as it should be. Also having struct  
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33)  *  fb_var_screeninfo and other data in fb_info pretty much eliminates the 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34)  *  need for get_fix and get_var. Once all drivers use the fix, var, and cmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35)  *  fbcon can be written around these fields. This will also eliminate the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36)  *  need to regenerate struct fb_var_screeninfo, struct fb_fix_screeninfo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37)  *  struct fb_cmap every time get_var, get_fix, get_cmap functions are called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38)  *  as many drivers do now. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40)  *  This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41)  *  License. See the file COPYING in the main directory of this archive for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42)  *  more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #include <linux/fb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56)     /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57)      *  This is just simple sample code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58)      *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59)      *  No warranty that it actually compiles.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60)      *  Even less warranty that it actually works :-)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64)  * Driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) static char *mode_option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69)  *  If your driver supports multiple boards, you should make the  
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70)  *  below data types arrays, or allocate them dynamically (using kmalloc()). 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71)  */ 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) /* 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74)  * This structure defines the hardware state of the graphics card. Normally
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75)  * you place this in a header file in linux/include/video. This file usually
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76)  * also includes register information. That allows other driver subsystems
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77)  * and userland applications the ability to use the same header file to 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78)  * avoid duplicate work and easy porting of software. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) struct xxx_par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83)  * Here we define the default structs fb_fix_screeninfo and fb_var_screeninfo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84)  * if we don't use modedb. If we do use modedb see xxxfb_init how to use it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85)  * to get a fb_var_screeninfo. Otherwise define a default var as well. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) static const struct fb_fix_screeninfo xxxfb_fix = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	.id =		"FB's name", 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	.type =		FB_TYPE_PACKED_PIXELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	.visual =	FB_VISUAL_PSEUDOCOLOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	.xpanstep =	1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	.ypanstep =	1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	.ywrapstep =	1, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	.accel =	FB_ACCEL_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97)     /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98)      * 	Modern graphical hardware not only supports pipelines but some 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99)      *  also support multiple monitors where each display can have its  
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100)      *  its own unique data. In this case each display could be  
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101)      *  represented by a separate framebuffer device thus a separate 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102)      *  struct fb_info. Now the struct xxx_par represents the graphics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103)      *  hardware state thus only one exist per card. In this case the 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104)      *  struct xxx_par for each graphics card would be shared between 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105)      *  every struct fb_info that represents a framebuffer on that card. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106)      *  This allows when one display changes it video resolution (info->var) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107)      *  the other displays know instantly. Each display can always be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108)      *  aware of the entire hardware state that affects it because they share
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109)      *  the same xxx_par struct. The other side of the coin is multiple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110)      *  graphics cards that pass data around until it is finally displayed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111)      *  on one monitor. Such examples are the voodoo 1 cards and high end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112)      *  NUMA graphics servers. For this case we have a bunch of pars, each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113)      *  one that represents a graphics state, that belong to one struct 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114)      *  fb_info. Their you would want to have *par point to a array of device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115)      *  states and have each struct fb_ops function deal with all those 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116)      *  states. I hope this covers every possible hardware design. If not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117)      *  feel free to send your ideas at jsimmons@users.sf.net 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120)     /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121)      *  If your driver supports multiple boards or it supports multiple 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122)      *  framebuffers, you should make these arrays, or allocate them 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123)      *  dynamically using framebuffer_alloc() and free them with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124)      *  framebuffer_release().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125)      */ 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) static struct fb_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128)     /* 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129)      * Each one represents the state of the hardware. Most hardware have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130)      * just one hardware state. These here represent the default state(s). 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) static struct xxx_par __initdata current_par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) int xxxfb_init(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137)  *	xxxfb_open - Optional function. Called when the framebuffer is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138)  *		     first accessed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139)  *	@info: frame buffer structure that represents a single frame buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140)  *	@user: tell us if the userland (value=1) or the console is accessing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141)  *	       the framebuffer. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143)  *	This function is the first function called in the framebuffer api.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144)  *	Usually you don't need to provide this function. The case where it 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145)  *	is used is to change from a text mode hardware state to a graphics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146)  * 	mode state. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148)  *	Returns negative errno on error, or zero on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) static int xxxfb_open(struct fb_info *info, int user)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156)  *	xxxfb_release - Optional function. Called when the framebuffer 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157)  *			device is closed. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158)  *	@info: frame buffer structure that represents a single frame buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159)  *	@user: tell us if the userland (value=1) or the console is accessing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160)  *	       the framebuffer. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161)  *	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162)  *	Thus function is called when we close /dev/fb or the framebuffer 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163)  *	console system is released. Usually you don't need this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164)  *	The case where it is usually used is to go from a graphics state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165)  *	to a text mode state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167)  *	Returns negative errno on error, or zero on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) static int xxxfb_release(struct fb_info *info, int user)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175)  *      xxxfb_check_var - Optional function. Validates a var passed in. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176)  *      @var: frame buffer variable screen structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177)  *      @info: frame buffer structure that represents a single frame buffer 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179)  *	Checks to see if the hardware supports the state requested by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180)  *	var passed in. This function does not alter the hardware state!!! 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181)  *	This means the data stored in struct fb_info and struct xxx_par do 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182)  *      not change. This includes the var inside of struct fb_info. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183)  *	Do NOT change these. This function can be called on its own if we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184)  *	intent to only test a mode and not actually set it. The stuff in 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185)  *	modedb.c is a example of this. If the var passed in is slightly 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186)  *	off by what the hardware can support then we alter the var PASSED in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187)  *	to what we can do.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189)  *      For values that are off, this function must round them _up_ to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190)  *      next value that is supported by the hardware.  If the value is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191)  *      greater than the highest value supported by the hardware, then this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192)  *      function must return -EINVAL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194)  *      Exception to the above rule:  Some drivers have a fixed mode, ie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195)  *      the hardware is already set at boot up, and cannot be changed.  In
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196)  *      this case, it is more acceptable that this function just return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197)  *      a copy of the currently working var (info->var). Better is to not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198)  *      implement this function, as the upper layer will do the copying
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199)  *      of the current var for you.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201)  *      Note:  This is the only function where the contents of var can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202)  *      freely adjusted after the driver has been registered. If you find
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203)  *      that you have code outside of this function that alters the content
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204)  *      of var, then you are doing something wrong.  Note also that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205)  *      contents of info->var must be left untouched at all times after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206)  *      driver registration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208)  *	Returns negative errno on error, or zero on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) static int xxxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212)     /* ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213)     return 0;	   	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217)  *      xxxfb_set_par - Optional function. Alters the hardware state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218)  *      @info: frame buffer structure that represents a single frame buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220)  *	Using the fb_var_screeninfo in fb_info we set the resolution of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221)  *	this particular framebuffer. This function alters the par AND the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222)  *	fb_fix_screeninfo stored in fb_info. It doesn't not alter var in 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223)  *	fb_info since we are using that data. This means we depend on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224)  *	data in var inside fb_info to be supported by the hardware. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226)  *      This function is also used to recover/restore the hardware to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227)  *      known working state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229)  *	xxxfb_check_var is always called before xxxfb_set_par to ensure that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230)  *      the contents of var is always valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232)  *	Again if you can't change the resolution you don't need this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234)  *      However, even if your hardware does not support mode changing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235)  *      a set_par might be needed to at least initialize the hardware to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236)  *      a known working state, especially if it came back from another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237)  *      process that also modifies the same hardware, such as X.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239)  *      If this is the case, a combination such as the following should work:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241)  *      static int xxxfb_check_var(struct fb_var_screeninfo *var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242)  *                                struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243)  *      {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244)  *              *var = info->var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245)  *              return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246)  *      }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248)  *      static int xxxfb_set_par(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249)  *      {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250)  *              init your hardware here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251)  *      }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253)  *	Returns negative errno on error, or zero on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) static int xxxfb_set_par(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257)     struct xxx_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258)     /* ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259)     return 0;	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263)  *  	xxxfb_setcolreg - Optional function. Sets a color register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264)  *      @regno: Which register in the CLUT we are programming 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265)  *      @red: The red value which can be up to 16 bits wide 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266)  *	@green: The green value which can be up to 16 bits wide 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267)  *	@blue:  The blue value which can be up to 16 bits wide.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268)  *	@transp: If supported, the alpha value which can be up to 16 bits wide.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269)  *      @info: frame buffer info structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270)  * 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271)  *  	Set a single color register. The values supplied have a 16 bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272)  *  	magnitude which needs to be scaled in this function for the hardware. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273)  *	Things to take into consideration are how many color registers, if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274)  *	any, are supported with the current color visual. With truecolor mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275)  *	no color palettes are supported. Here a pseudo palette is created
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276)  *	which we store the value in pseudo_palette in struct fb_info. For
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277)  *	pseudocolor mode we have a limited color palette. To deal with this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278)  *	we can program what color is displayed for a particular pixel value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279)  *	DirectColor is similar in that we can program each color field. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280)  *	we have a static colormap we don't need to implement this function. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281)  * 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282)  *	Returns negative errno on error, or zero on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 			   unsigned blue, unsigned transp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 			   struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288)     if (regno >= 256)  /* no. of hw registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289)        return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290)     /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291)      * Program hardware... do anything you want with transp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294)     /* grayscale works only partially under directcolor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295)     if (info->var.grayscale) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296)        /* grayscale = 0.30*R + 0.59*G + 0.11*B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297)        red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300)     /* Directcolor:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301)      *   var->{color}.offset contains start of bitfield
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302)      *   var->{color}.length contains length of bitfield
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303)      *   {hardwarespecific} contains width of DAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304)      *   pseudo_palette[X] is programmed to (X << red.offset) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305)      *                                      (X << green.offset) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306)      *                                      (X << blue.offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307)      *   RAMDAC[X] is programmed to (red, green, blue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308)      *   color depth = SUM(var->{color}.length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309)      *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310)      * Pseudocolor:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311)      *    var->{color}.offset is 0 unless the palette index takes less than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312)      *                        bits_per_pixel bits and is stored in the upper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313)      *                        bits of the pixel value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314)      *    var->{color}.length is set so that 1 << length is the number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315)      *                        available palette entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316)      *    pseudo_palette is not used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317)      *    RAMDAC[X] is programmed to (red, green, blue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318)      *    color depth = var->{color}.length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319)      *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320)      * Static pseudocolor:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321)      *    same as Pseudocolor, but the RAMDAC is not programmed (read-only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322)      *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323)      * Mono01/Mono10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324)      *    Has only 2 values, black on white or white on black (fg on bg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325)      *    var->{color}.offset is 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326)      *    white = (1 << var->{color}.length) - 1, black = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327)      *    pseudo_palette is not used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328)      *    RAMDAC does not exist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329)      *    color depth is always 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330)      *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331)      * Truecolor:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332)      *    does not use RAMDAC (usually has 3 of them).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333)      *    var->{color}.offset contains start of bitfield
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334)      *    var->{color}.length contains length of bitfield
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335)      *    pseudo_palette is programmed to (red << red.offset) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336)      *                                    (green << green.offset) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337)      *                                    (blue << blue.offset) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338)      *                                    (transp << transp.offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339)      *    RAMDAC does not exist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340)      *    color depth = SUM(var->{color}.length})
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341)      *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342)      *  The color depth is used by fbcon for choosing the logo and also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343)      *  for color palette transformation if color depth < 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344)      *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345)      *  As can be seen from the above, the field bits_per_pixel is _NOT_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346)      *  a criteria for describing the color visual.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347)      *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348)      *  A common mistake is assuming that bits_per_pixel <= 8 is pseudocolor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349)      *  and higher than that, true/directcolor.  This is incorrect, one needs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350)      *  to look at the fix->visual.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351)      *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352)      *  Another common mistake is using bits_per_pixel to calculate the color
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353)      *  depth.  The bits_per_pixel field does not directly translate to color
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354)      *  depth. You have to compute for the color depth (using the color
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355)      *  bitfields) and fix->visual as seen above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358)     /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359)      * This is the point where the color is converted to something that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360)      * is acceptable by the hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) #define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363)     red = CNVT_TOHW(red, info->var.red.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364)     green = CNVT_TOHW(green, info->var.green.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365)     blue = CNVT_TOHW(blue, info->var.blue.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366)     transp = CNVT_TOHW(transp, info->var.transp.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) #undef CNVT_TOHW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368)     /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369)      * This is the point where the function feeds the color to the hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370)      * palette after converting the colors to something acceptable by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371)      * the hardware. Note, only FB_VISUAL_DIRECTCOLOR and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372)      * FB_VISUAL_PSEUDOCOLOR visuals need to write to the hardware palette.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373)      * If you have code that writes to the hardware CLUT, and it's not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374)      * any of the above visuals, then you are doing something wrong.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376)     if (info->fix.visual == FB_VISUAL_DIRECTCOLOR ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	info->fix.visual == FB_VISUAL_TRUECOLOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	    write_{red|green|blue|transp}_to_clut();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380)     /* This is the point were you need to fill up the contents of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381)      * info->pseudo_palette. This structure is used _only_ by fbcon, thus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382)      * it only contains 16 entries to match the number of colors supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383)      * by the console. The pseudo_palette is used only if the visual is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384)      * in directcolor or truecolor mode.  With other visuals, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385)      * pseudo_palette is not used. (This might change in the future.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386)      *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387)      * The contents of the pseudo_palette is in raw pixel format.  Ie, each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388)      * entry can be written directly to the framebuffer without any conversion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389)      * The pseudo_palette is (void *).  However, if using the generic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390)      * drawing functions (cfb_imageblit, cfb_fillrect), the pseudo_palette
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391)      * must be casted to (u32 *) _regardless_ of the bits per pixel. If the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392)      * driver is using its own drawing functions, then it can use whatever
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393)      * size it wants.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395)     if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	    u32 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	    if (regno >= 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 		    return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	    v = (red << info->var.red.offset) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 		    (green << info->var.green.offset) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 		    (blue << info->var.blue.offset) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 		    (transp << info->var.transp.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	    ((u32*)(info->pseudo_palette))[regno] = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410)     /* ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415)  *      xxxfb_pan_display - NOT a required function. Pans the display.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416)  *      @var: frame buffer variable screen structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417)  *      @info: frame buffer structure that represents a single frame buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419)  *	Pan (or wrap, depending on the `vmode' field) the display using the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420)  *  	`xoffset' and `yoffset' fields of the `var' structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421)  *  	If the values don't fit, return -EINVAL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423)  *      Returns negative errno on error, or zero on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) static int xxxfb_pan_display(struct fb_var_screeninfo *var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 			     struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428)     /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429)      * If your hardware does not support panning, _do_ _not_ implement this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430)      * function. Creating a dummy function will just confuse user apps.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433)     /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434)      * Note that even if this function is fully functional, a setting of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435)      * 0 in both xpanstep and ypanstep means that this function will never
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436)      * get called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439)     /* ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444)  *      xxxfb_blank - NOT a required function. Blanks the display.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445)  *      @blank_mode: the blank mode we want. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446)  *      @info: frame buffer structure that represents a single frame buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448)  *      Blank the screen if blank_mode != FB_BLANK_UNBLANK, else unblank.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449)  *      Return 0 if blanking succeeded, != 0 if un-/blanking failed due to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450)  *      e.g. a video mode which doesn't support it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452)  *      Implements VESA suspend and powerdown modes on hardware that supports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453)  *      disabling hsync/vsync:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455)  *      FB_BLANK_NORMAL = display is blanked, syncs are on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456)  *      FB_BLANK_HSYNC_SUSPEND = hsync off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457)  *      FB_BLANK_VSYNC_SUSPEND = vsync off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458)  *      FB_BLANK_POWERDOWN =  hsync and vsync off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460)  *      If implementing this function, at least support FB_BLANK_UNBLANK.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461)  *      Return !0 for any modes that are unimplemented.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) static int xxxfb_blank(int blank_mode, struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466)     /* ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) /* ------------ Accelerated Functions --------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473)  * We provide our own functions if we have hardware acceleration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474)  * or non packed pixel format layouts. If we have no hardware 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475)  * acceleration, we can use a generic unaccelerated function. If using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476)  * a pack pixel format just use the functions in cfb_*.c. Each file 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477)  * has one of the three different accel functions we support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481)  *      xxxfb_fillrect - REQUIRED function. Can use generic routines if 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482)  *		 	 non acclerated hardware and packed pixel based.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483)  *			 Draws a rectangle on the screen.		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485)  *      @info: frame buffer structure that represents a single frame buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486)  *	@region: The structure representing the rectangular region we 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487)  *		 wish to draw to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489)  *	This drawing operation places/removes a retangle on the screen 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490)  *	depending on the rastering operation with the value of color which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491)  *	is in the current color depth format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) void xxxfb_fillrect(struct fb_info *p, const struct fb_fillrect *region)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) /*	Meaning of struct fb_fillrect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497)  *	@dx: The x and y corrdinates of the upper left hand corner of the 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498)  *	@dy: area we want to draw to. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499)  *	@width: How wide the rectangle is we want to draw.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500)  *	@height: How tall the rectangle is we want to draw.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501)  *	@color:	The color to fill in the rectangle with. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502)  *	@rop: The raster operation. We can draw the rectangle with a COPY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503)  *	      of XOR which provides erasing effect. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508)  *      xxxfb_copyarea - REQUIRED function. Can use generic routines if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509)  *                       non acclerated hardware and packed pixel based.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510)  *                       Copies one area of the screen to another area.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512)  *      @info: frame buffer structure that represents a single frame buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513)  *      @area: Structure providing the data to copy the framebuffer contents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514)  *	       from one region to another.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516)  *      This drawing operation copies a rectangular area from one area of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517)  *	screen to another area.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) void xxxfb_copyarea(struct fb_info *p, const struct fb_copyarea *area) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522)  *      @dx: The x and y coordinates of the upper left hand corner of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523)  *	@dy: destination area on the screen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524)  *      @width: How wide the rectangle is we want to copy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525)  *      @height: How tall the rectangle is we want to copy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526)  *      @sx: The x and y coordinates of the upper left hand corner of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527)  *      @sy: source area on the screen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533)  *      xxxfb_imageblit - REQUIRED function. Can use generic routines if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534)  *                        non acclerated hardware and packed pixel based.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535)  *                        Copies a image from system memory to the screen. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537)  *      @info: frame buffer structure that represents a single frame buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538)  *	@image:	structure defining the image.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540)  *      This drawing operation draws a image on the screen. It can be a 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541)  *	mono image (needed for font handling) or a color image (needed for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542)  *	tux). 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) void xxxfb_imageblit(struct fb_info *p, const struct fb_image *image) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547)  *      @dx: The x and y coordinates of the upper left hand corner of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548)  *	@dy: destination area to place the image on the screen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549)  *      @width: How wide the image is we want to copy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550)  *      @height: How tall the image is we want to copy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551)  *      @fg_color: For mono bitmap images this is color data for     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552)  *      @bg_color: the foreground and background of the image to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553)  *		   write directly to the frmaebuffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554)  *	@depth:	How many bits represent a single pixel for this image.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555)  *	@data: The actual data used to construct the image on the display.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556)  *	@cmap: The colormap used for color images.   
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560)  * The generic function, cfb_imageblit, expects that the bitmap scanlines are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561)  * padded to the next byte.  Most hardware accelerators may require padding to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562)  * the next u16 or the next u32.  If that is the case, the driver can specify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563)  * this by setting info->pixmap.scan_align = 2 or 4.  See a more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564)  * comprehensive description of the pixmap below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569)  *	xxxfb_cursor - 	OPTIONAL. If your hardware lacks support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570)  *			for a cursor, leave this field NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572)  *      @info: frame buffer structure that represents a single frame buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573)  *	@cursor: structure defining the cursor to draw.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575)  *      This operation is used to set or alter the properities of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576)  *	cursor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578)  *	Returns negative errno on error, or zero on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) int xxxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583)  *      @set: 	Which fields we are altering in struct fb_cursor 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584)  *	@enable: Disable or enable the cursor 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585)  *      @rop: 	The bit operation we want to do. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586)  *      @mask:  This is the cursor mask bitmap. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587)  *      @dest:  A image of the area we are going to display the cursor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588)  *		Used internally by the driver.	 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589)  *      @hot:	The hot spot. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590)  *	@image:	The actual data for the cursor image.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592)  *      NOTES ON FLAGS (cursor->set):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594)  *      FB_CUR_SETIMAGE - the cursor image has changed (cursor->image.data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595)  *      FB_CUR_SETPOS   - the cursor position has changed (cursor->image.dx|dy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596)  *      FB_CUR_SETHOT   - the cursor hot spot has changed (cursor->hot.dx|dy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597)  *      FB_CUR_SETCMAP  - the cursor colors has changed (cursor->fg_color|bg_color)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598)  *      FB_CUR_SETSHAPE - the cursor bitmask has changed (cursor->mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599)  *      FB_CUR_SETSIZE  - the cursor size has changed (cursor->width|height)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600)  *      FB_CUR_SETALL   - everything has changed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602)  *      NOTES ON ROPs (cursor->rop, Raster Operation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604)  *      ROP_XOR         - cursor->image.data XOR cursor->mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605)  *      ROP_COPY        - curosr->image.data AND cursor->mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607)  *      OTHER NOTES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609)  *      - fbcon only supports a 2-color cursor (cursor->image.depth = 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610)  *      - The fb_cursor structure, @cursor, _will_ always contain valid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611)  *        fields, whether any particular bitfields in cursor->set is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612)  *        or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617)  *	xxxfb_sync - NOT a required function. Normally the accel engine 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618)  *		     for a graphics card take a specific amount of time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619)  *		     Often we have to wait for the accelerator to finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620)  *		     its operation before we can write to the framebuffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621)  *		     so we can have consistent display output. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623)  *      @info: frame buffer structure that represents a single frame buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625)  *      If the driver has implemented its own hardware-based drawing function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626)  *      implementing this function is highly recommended.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) int xxxfb_sync(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633)     /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634)      *  Frame buffer operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) static const struct fb_ops xxxfb_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	.owner		= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	.fb_open	= xxxfb_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	.fb_read	= xxxfb_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	.fb_write	= xxxfb_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	.fb_release	= xxxfb_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	.fb_check_var	= xxxfb_check_var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	.fb_set_par	= xxxfb_set_par,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	.fb_setcolreg	= xxxfb_setcolreg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	.fb_blank	= xxxfb_blank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	.fb_pan_display	= xxxfb_pan_display,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	.fb_fillrect	= xxxfb_fillrect, 	/* Needed !!! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	.fb_copyarea	= xxxfb_copyarea,	/* Needed !!! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	.fb_imageblit	= xxxfb_imageblit,	/* Needed !!! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	.fb_cursor	= xxxfb_cursor,		/* Optional !!! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	.fb_sync	= xxxfb_sync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	.fb_ioctl	= xxxfb_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	.fb_mmap	= xxxfb_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) /* ------------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659)     /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660)      *  Initialization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) /* static int __init xxfb_probe (struct platform_device *pdev) -- for platform devs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) static int xxxfb_probe(struct pci_dev *dev, const struct pci_device_id *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666)     struct fb_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667)     struct xxx_par *par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668)     struct device *device = &dev->dev; /* or &pdev->dev */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669)     int cmap_len, retval;	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670)    
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671)     /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672)      * Dynamically allocate info and par
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674)     info = framebuffer_alloc(sizeof(struct xxx_par), device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676)     if (!info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	    /* goto error path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680)     par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682)     /* 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683)      * Here we set the screen_base to the virtual memory address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684)      * for the framebuffer. Usually we obtain the resource address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685)      * from the bus layer and then translate it to virtual memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686)      * space via ioremap. Consult ioport.h. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688)     info->screen_base = framebuffer_virtual_memory;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689)     info->fbops = &xxxfb_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690)     info->fix = xxxfb_fix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691)     info->pseudo_palette = pseudo_palette; /* The pseudopalette is an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 					    * 16-member array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 					    */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694)     /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695)      * Set up flags to indicate what sort of acceleration your
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696)      * driver can provide (pan/wrap/copyarea/etc.) and whether it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697)      * is a module -- see FBINFO_* in include/linux/fb.h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698)      *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699)      * If your hardware can support any of the hardware accelerated functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700)      * fbcon performance will improve if info->flags is set properly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701)      *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702)      * FBINFO_HWACCEL_COPYAREA - hardware moves
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703)      * FBINFO_HWACCEL_FILLRECT - hardware fills
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704)      * FBINFO_HWACCEL_IMAGEBLIT - hardware mono->color expansion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705)      * FBINFO_HWACCEL_YPAN - hardware can pan display in y-axis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706)      * FBINFO_HWACCEL_YWRAP - hardware can wrap display in y-axis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707)      * FBINFO_HWACCEL_DISABLED - supports hardware accels, but disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708)      * FBINFO_READS_FAST - if set, prefer moves over mono->color expansion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709)      * FBINFO_MISC_TILEBLITTING - hardware can do tile blits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710)      *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711)      * NOTE: These are for fbcon use only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713)     info->flags = FBINFO_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) /********************* This stage is optional ******************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716)      /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717)      * The struct pixmap is a scratch pad for the drawing functions. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718)      * is where the monochrome bitmap is constructed by the higher layers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719)      * and then passed to the accelerator.  For drivers that uses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720)      * cfb_imageblit, you can skip this part.  For those that have a more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721)      * rigorous requirement, this stage is needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724)     /* PIXMAP_SIZE should be small enough to optimize drawing, but not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725)      * large enough that memory is wasted.  A safe size is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726)      * (max_xres * max_font_height/8). max_xres is driver dependent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727)      * max_font_height is 32.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729)     info->pixmap.addr = kmalloc(PIXMAP_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730)     if (!info->pixmap.addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	    /* goto error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734)     info->pixmap.size = PIXMAP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736)     /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737)      * FB_PIXMAP_SYSTEM - memory is in system ram
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738)      * FB_PIXMAP_IO     - memory is iomapped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739)      * FB_PIXMAP_SYNC   - if set, will call fb_sync() per access to pixmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740)      *                    usually if FB_PIXMAP_IO is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741)      *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742)      * Currently, FB_PIXMAP_IO is unimplemented.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744)     info->pixmap.flags = FB_PIXMAP_SYSTEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746)     /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747)      * scan_align is the number of padding for each scanline.  It is in bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748)      * Thus for accelerators that need padding to the next u32, put 4 here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750)     info->pixmap.scan_align = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752)     /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753)      * buf_align is the amount to be padded for the buffer. For example,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754)      * the i810fb needs a scan_align of 2 but expects it to be fed with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755)      * dwords, so a buf_align = 4 is required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757)     info->pixmap.buf_align = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759)     /* access_align is how many bits can be accessed from the framebuffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760)      * ie. some epson cards allow 16-bit access only.  Most drivers will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761)      * be safe with u32 here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762)      *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763)      * NOTE: This field is currently unused.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765)     info->pixmap.access_align = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) /***************************** End optional stage ***************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768)     /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769)      * This should give a reasonable default video mode. The following is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770)      * done when we can set a video mode. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772)     if (!mode_option)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	mode_option = "640x480@60";	 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775)     retval = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776)   
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777)     if (!retval || retval == 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	return -EINVAL;			
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780)     /* This has to be done! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781)     if (fb_alloc_cmap(&info->cmap, cmap_len, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784)     /* 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785)      * The following is done in the case of having hardware with a static 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786)      * mode. If we are setting the mode ourselves we don't call this. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787)      */	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788)     info->var = xxxfb_var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790)     /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791)      * For drivers that can...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793)     xxxfb_check_var(&info->var, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795)     /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796)      * Does a call to fb_set_par() before register_framebuffer needed?  This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797)      * will depend on you and the hardware.  If you are sure that your driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798)      * is the only device in the system, a call to fb_set_par() is safe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799)      *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800)      * Hardware in x86 systems has a VGA core.  Calling set_par() at this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801)      * point will corrupt the VGA console, so it might be safer to skip a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802)      * call to set_par here and just allow fbcon to do it for you.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804)     /* xxxfb_set_par(info); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806)     if (register_framebuffer(info) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	fb_dealloc_cmap(&info->cmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810)     fb_info(info, "%s frame buffer device\n", info->fix.id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811)     pci_set_drvdata(dev, info); /* or platform_set_drvdata(pdev, info) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815)     /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816)      *  Cleanup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) /* static void xxxfb_remove(struct platform_device *pdev) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) static void xxxfb_remove(struct pci_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	struct fb_info *info = pci_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	/* or platform_get_drvdata(pdev); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	if (info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 		unregister_framebuffer(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 		fb_dealloc_cmap(&info->cmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 		/* ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 		framebuffer_release(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) #ifdef CONFIG_PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835)  *	xxxfb_suspend - Optional but recommended function. Suspend the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836)  *	@dev: PCI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837)  *	@msg: the suspend event code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839)  *      See Documentation/driver-api/pm/devices.rst for more information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) static int xxxfb_suspend(struct pci_dev *dev, pm_message_t msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	struct fb_info *info = pci_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	struct xxxfb_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	/* suspend here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851)  *	xxxfb_resume - Optional but recommended function. Resume the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852)  *	@dev: PCI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854)  *      See Documentation/driver-api/pm/devices.rst for more information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) static int xxxfb_resume(struct pci_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	struct fb_info *info = pci_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	struct xxxfb_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	/* resume here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) #define xxxfb_suspend NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) #define xxxfb_resume NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) #endif /* CONFIG_PM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) static const struct pci_device_id xxxfb_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	{ PCI_VENDOR_ID_XXX, PCI_DEVICE_ID_XXX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	  PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	  PCI_CLASS_MASK, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	{ 0, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) /* For PCI drivers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) static struct pci_driver xxxfb_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	.name =		"xxxfb",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	.id_table =	xxxfb_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	.probe =	xxxfb_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	.remove =	xxxfb_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	.suspend =      xxxfb_suspend, /* optional but recommended */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	.resume =       xxxfb_resume,  /* optional but recommended */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) MODULE_DEVICE_TABLE(pci, xxxfb_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) int __init xxxfb_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	 *  For kernel boot options (in 'video=xxxfb:<options>' format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) #ifndef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	char *option = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	if (fb_get_options("xxxfb", &option))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	xxxfb_setup(option);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	return pci_register_driver(&xxxfb_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) static void __exit xxxfb_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	pci_unregister_driver(&xxxfb_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) #else /* non PCI, platform drivers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) /* for platform devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914)  *	xxxfb_suspend - Optional but recommended function. Suspend the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915)  *	@dev: platform device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916)  *	@msg: the suspend event code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918)  *      See Documentation/driver-api/pm/devices.rst for more information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) static int xxxfb_suspend(struct platform_device *dev, pm_message_t msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	struct fb_info *info = platform_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	struct xxxfb_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	/* suspend here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930)  *	xxxfb_resume - Optional but recommended function. Resume the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931)  *	@dev: platform device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933)  *      See Documentation/driver-api/pm/devices.rst for more information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) static int xxxfb_resume(struct platform_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	struct fb_info *info = platform_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	struct xxxfb_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	/* resume here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) #define xxxfb_suspend NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) #define xxxfb_resume NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) #endif /* CONFIG_PM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) static struct platform_device_driver xxxfb_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	.probe = xxxfb_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	.remove = xxxfb_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	.suspend = xxxfb_suspend, /* optional but recommended */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	.resume = xxxfb_resume,   /* optional but recommended */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 		.name = "xxxfb",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) static struct platform_device *xxxfb_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) #ifndef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961)     /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962)      *  Setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966)  * Only necessary if your driver takes special options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967)  * otherwise we fall back on the generic fb_setup().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) int __init xxxfb_setup(char *options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971)     /* Parse user specified options (`video=xxxfb:') */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) #endif /* MODULE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) static int __init xxxfb_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	 *  For kernel boot options (in 'video=xxxfb:<options>' format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) #ifndef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	char *option = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	if (fb_get_options("xxxfb", &option))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	xxxfb_setup(option);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	ret = platform_driver_register(&xxxfb_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		xxxfb_device = platform_device_register_simple("xxxfb", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 								NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 		if (IS_ERR(xxxfb_device)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 			platform_driver_unregister(&xxxfb_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 			ret = PTR_ERR(xxxfb_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) static void __exit xxxfb_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	platform_device_unregister(xxxfb_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	platform_driver_unregister(&xxxfb_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) #endif /* CONFIG_PCI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) /* ------------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)     /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)      *  Modularization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) module_init(xxxfb_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) module_exit(xxxfb_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) MODULE_LICENSE("GPL");