⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modedb.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	mode->hsync_len = var->hsync_len;	mode->vsync_len = var->vsync_len;	mode->left_margin = var->left_margin;	mode->right_margin = var->right_margin;	mode->upper_margin = var->upper_margin;	mode->lower_margin = var->lower_margin;	mode->sync = var->sync;	mode->vmode = var->vmode & FB_VMODE_MASK;	mode->flag = FB_MODE_IS_FROM_VAR;	mode->refresh = 0;	if (!var->pixclock)		return;	pixclock = PICOS2KHZ(var->pixclock) * 1000;	htotal = var->xres + var->right_margin + var->hsync_len +		var->left_margin;	vtotal = var->yres + var->lower_margin + var->vsync_len +		var->upper_margin;	if (var->vmode & FB_VMODE_INTERLACED)		vtotal /= 2;	if (var->vmode & FB_VMODE_DOUBLE)		vtotal *= 2;	hfreq = pixclock/htotal;	mode->refresh = hfreq/vtotal;}/** * fb_videomode_to_var - convert fb_videomode to fb_var_screeninfo * @var: pointer to struct fb_var_screeninfo * @mode: pointer to struct fb_videomode */void fb_videomode_to_var(struct fb_var_screeninfo *var,			 const struct fb_videomode *mode){	var->xres = mode->xres;	var->yres = mode->yres;	var->xres_virtual = mode->xres;	var->yres_virtual = mode->yres;	var->xoffset = 0;	var->yoffset = 0;	var->pixclock = mode->pixclock;	var->left_margin = mode->left_margin;	var->right_margin = mode->right_margin;	var->upper_margin = mode->upper_margin;	var->lower_margin = mode->lower_margin;	var->hsync_len = mode->hsync_len;	var->vsync_len = mode->vsync_len;	var->sync = mode->sync;	var->vmode = mode->vmode & FB_VMODE_MASK;}/** * fb_mode_is_equal - compare 2 videomodes * @mode1: first videomode * @mode2: second videomode * * RETURNS: * 1 if equal, 0 if not */int fb_mode_is_equal(const struct fb_videomode *mode1,		     const struct fb_videomode *mode2){	return (mode1->xres         == mode2->xres &&		mode1->yres         == mode2->yres &&		mode1->pixclock     == mode2->pixclock &&		mode1->hsync_len    == mode2->hsync_len &&		mode1->vsync_len    == mode2->vsync_len &&		mode1->left_margin  == mode2->left_margin &&		mode1->right_margin == mode2->right_margin &&		mode1->upper_margin == mode2->upper_margin &&		mode1->lower_margin == mode2->lower_margin &&		mode1->sync         == mode2->sync &&		mode1->vmode        == mode2->vmode);}/** * fb_find_best_mode - find best matching videomode * @var: pointer to struct fb_var_screeninfo * @head: pointer to struct list_head of modelist * * RETURNS: * struct fb_videomode, NULL if none found * * IMPORTANT: * This function assumes that all modelist entries in * info->modelist are valid. * * NOTES: * Finds best matching videomode which has an equal or greater dimension than * var->xres and var->yres.  If more than 1 videomode is found, will return * the videomode with the highest refresh rate */const struct fb_videomode *fb_find_best_mode(const struct fb_var_screeninfo *var,					     struct list_head *head){	struct list_head *pos;	struct fb_modelist *modelist;	struct fb_videomode *mode, *best = NULL;	u32 diff = -1;	list_for_each(pos, head) {		u32 d;		modelist = list_entry(pos, struct fb_modelist, list);		mode = &modelist->mode;		if (mode->xres >= var->xres && mode->yres >= var->yres) {			d = (mode->xres - var->xres) +				(mode->yres - var->yres);			if (diff > d) {				diff = d;				best = mode;			} else if (diff == d && best &&				   mode->refresh > best->refresh)				best = mode;		}	}	return best;}/** * fb_find_nearest_mode - find closest videomode * * @mode: pointer to struct fb_videomode * @head: pointer to modelist * * Finds best matching videomode, smaller or greater in dimension. * If more than 1 videomode is found, will return the videomode with * the closest refresh rate. */const struct fb_videomode *fb_find_nearest_mode(const struct fb_videomode *mode,					        struct list_head *head){	struct list_head *pos;	struct fb_modelist *modelist;	struct fb_videomode *cmode, *best = NULL;	u32 diff = -1, diff_refresh = -1;	list_for_each(pos, head) {		u32 d;		modelist = list_entry(pos, struct fb_modelist, list);		cmode = &modelist->mode;		d = abs(cmode->xres - mode->xres) +			abs(cmode->yres - mode->yres);		if (diff > d) {			diff = d;			best = cmode;		} else if (diff == d) {			d = abs(cmode->refresh - mode->refresh);			if (diff_refresh > d) {				diff_refresh = d;				best = cmode;			}		}	}	return best;}/** * fb_match_mode - find a videomode which exactly matches the timings in var * @var: pointer to struct fb_var_screeninfo * @head: pointer to struct list_head of modelist * * RETURNS: * struct fb_videomode, NULL if none found */const struct fb_videomode *fb_match_mode(const struct fb_var_screeninfo *var,					 struct list_head *head){	struct list_head *pos;	struct fb_modelist *modelist;	struct fb_videomode *m, mode;	fb_var_to_videomode(&mode, var);	list_for_each(pos, head) {		modelist = list_entry(pos, struct fb_modelist, list);		m = &modelist->mode;		if (fb_mode_is_equal(m, &mode))			return m;	}	return NULL;}/** * fb_add_videomode: adds videomode entry to modelist * @mode: videomode to add * @head: struct list_head of modelist * * NOTES: * Will only add unmatched mode entries */int fb_add_videomode(const struct fb_videomode *mode, struct list_head *head){	struct list_head *pos;	struct fb_modelist *modelist;	struct fb_videomode *m;	int found = 0;	list_for_each(pos, head) {		modelist = list_entry(pos, struct fb_modelist, list);		m = &modelist->mode;		if (fb_mode_is_equal(m, mode)) {			found = 1;			break;		}	}	if (!found) {		modelist = kmalloc(sizeof(struct fb_modelist),						  GFP_KERNEL);		if (!modelist)			return -ENOMEM;		modelist->mode = *mode;		list_add(&modelist->list, head);	}	return 0;}/** * fb_delete_videomode: removed videomode entry from modelist * @mode: videomode to remove * @head: struct list_head of modelist * * NOTES: * Will remove all matching mode entries */void fb_delete_videomode(const struct fb_videomode *mode,			 struct list_head *head){	struct list_head *pos, *n;	struct fb_modelist *modelist;	struct fb_videomode *m;	list_for_each_safe(pos, n, head) {		modelist = list_entry(pos, struct fb_modelist, list);		m = &modelist->mode;		if (fb_mode_is_equal(m, mode)) {			list_del(pos);			kfree(pos);		}	}}/** * fb_destroy_modelist: destroy modelist * @head: struct list_head of modelist */void fb_destroy_modelist(struct list_head *head){	struct list_head *pos, *n;	list_for_each_safe(pos, n, head) {		list_del(pos);		kfree(pos);	}}EXPORT_SYMBOL_GPL(fb_destroy_modelist);/** * fb_videomode_to_modelist: convert mode array to mode list * @modedb: array of struct fb_videomode * @num: number of entries in array * @head: struct list_head of modelist */void fb_videomode_to_modelist(const struct fb_videomode *modedb, int num,			      struct list_head *head){	int i;	INIT_LIST_HEAD(head);	for (i = 0; i < num; i++) {		if (fb_add_videomode(&modedb[i], head))			return;	}}const struct fb_videomode *fb_find_best_display(const struct fb_monspecs *specs,					        struct list_head *head){	struct list_head *pos;	struct fb_modelist *modelist;	const struct fb_videomode *m, *m1 = NULL, *md = NULL, *best = NULL;	int first = 0;	if (!head->prev || !head->next || list_empty(head))		goto finished;	/* get the first detailed mode and the very first mode */	list_for_each(pos, head) {		modelist = list_entry(pos, struct fb_modelist, list);		m = &modelist->mode;		if (!first) {			m1 = m;			first = 1;		}		if (m->flag & FB_MODE_IS_FIRST) { 			md = m;			break;		}	}	/* first detailed timing is preferred */	if (specs->misc & FB_MISC_1ST_DETAIL) {		best = md;		goto finished;	}	/* find best mode based on display width and height */	if (specs->max_x && specs->max_y) {		struct fb_var_screeninfo var;		memset(&var, 0, sizeof(struct fb_var_screeninfo));		var.xres = (specs->max_x * 7200)/254;		var.yres = (specs->max_y * 7200)/254;		m = fb_find_best_mode(&var, head);		if (m) {			best = m;			goto finished;		}	}	/* use first detailed mode */	if (md) {		best = md;		goto finished;	}	/* last resort, use the very first mode */	best = m1;finished:	return best;}EXPORT_SYMBOL(fb_find_best_display);EXPORT_SYMBOL(fb_videomode_to_var);EXPORT_SYMBOL(fb_var_to_videomode);EXPORT_SYMBOL(fb_mode_is_equal);EXPORT_SYMBOL(fb_add_videomode);EXPORT_SYMBOL(fb_match_mode);EXPORT_SYMBOL(fb_find_best_mode);EXPORT_SYMBOL(fb_find_nearest_mode);EXPORT_SYMBOL(fb_videomode_to_modelist);EXPORT_SYMBOL(fb_find_mode);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -