^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");