亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? s3c2410fb.c

?? 嵌入式平臺下的LCD驅(qū)動源代碼
?? C
?? 第 1 頁 / 共 2 頁
字號:
/*
 * linux/drivers/video/s3c2410fb.c
 *	Copyright (c) Arnaud Patard, Ben Dooks
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file COPYING in the main directory of this archive for
 * more details.
 *
 *	    S3C2410 LCD Controller Frame Buffer Driver
 *	    based on skeletonfb.c, sa1100fb.c and others
 *
 * ChangeLog
 *
 * 2005-12-26   : godori(www.aesop-embedded.org)<ghcstop@gmail.com>
 *      - pixclock routine change(why?: because 6.4", 4", 7" lcd )
 *
 * 2005-12   : godori(www.aesop-embedded.org)<ghcstop@gmail.com>
 *      - LCD use static memory(no dynamic dma alloc)
 *      - register setting control
 *
 * 2005-04-07: Arnaud Patard <arnaud.patard@rtp-net.org>
 *      - u32 state -> pm_message_t state
 *      - S3C2410_{VA,SZ}_LCD -> S3C24XX
 *
 * 2005-03-15: Arnaud Patard <arnaud.patard@rtp-net.org>
 *      - Removed the ioctl
 *      - use readl/writel instead of __raw_writel/__raw_readl
 *
 * 2004-12-04: Arnaud Patard <arnaud.patard@rtp-net.org>
 *      - Added the possibility to set on or off the
 *      debugging mesaages
 *      - Replaced 0 and 1 by on or off when reading the
 *      /sys files
 *
 * 2005-03-23: Ben Dooks <ben-linux@fluff.org>
 *	- added non 16bpp modes
 *	- updated platform information for range of x/y/bpp
 *	- add code to ensure palette is written correctly
 *	- add pixel clock divisor control
 *
 * 2004-11-11: Arnaud Patard <arnaud.patard@rtp-net.org>
 * 	- Removed the use of currcon as it no more exist
 * 	- Added LCD power sysfs interface
 *
 * 2004-11-03: Ben Dooks <ben-linux@fluff.org>
 *	- minor cleanups
 *	- add suspend/resume support
 *	- s3c2410fb_setcolreg() not valid in >8bpp modes
 *	- removed last CONFIG_FB_S3C2410_FIXED
 *	- ensure lcd controller stopped before cleanup
 *	- added sysfs interface for backlight power
 *	- added mask for gpio configuration
 *	- ensured IRQs disabled during GPIO configuration
 *	- disable TPAL before enabling video
 *
 * 2004-09-20: Arnaud Patard <arnaud.patard@rtp-net.org>
 *      - Suppress command line options
 *
 * 2004-09-15: Arnaud Patard <arnaud.patard@rtp-net.org>
 * 	- code cleanup
 *
 * 2004-09-07: Arnaud Patard <arnaud.patard@rtp-net.org>
 * 	- Renamed from h1940fb.c to s3c2410fb.c
 * 	- Add support for different devices
 * 	- Backlight support
 *
 * 2004-09-05: Herbert P鰐zl <herbert@13thfloor.at>
 *	- added clock (de-)allocation code
 *	- added fixem fbmem option
 *
 * 2004-07-27: Arnaud Patard <arnaud.patard@rtp-net.org>
 *	- code cleanup
 *	- added a forgotten return in h1940fb_init
 *
 * 2004-07-19: Herbert P鰐zl <herbert@13thfloor.at>
 *	- code cleanup and extended debugging
 *
 * 2004-07-15: Arnaud Patard <arnaud.patard@rtp-net.org>
 *	- First version
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/string.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/wait.h>

#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/div64.h>

#include <asm/mach/map.h>
#include <asm/arch/regs-lcd.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/fb.h>
#include <asm/hardware/clock.h>


#ifdef CONFIG_PM
#include <linux/pm.h>
#endif

#include "s3c2410fb.h"


static struct s3c2410fb_info	   info;


static struct s3c2410fb_mach_info *mach_info;

/* Debugging stuff */
#ifdef CONFIG_FB_S3C2410_DEBUG
static int debug	   = 1;
#else
static int debug	   = 0;
#endif

#define dprintk(msg...)	if (debug) { printk(KERN_DEBUG "s3c2410fb: " msg); }


//#define GDEBUG // ghcstop
#ifdef  GDEBUG
#    define gprintk( x... )  printk( x )
#else
#    define gprintk( x... )
#endif



/* useful functions */

static inline struct s3c2410fb_info *fb_to_s3cfb(struct fb_info *info)
{
	return container_of(info, struct s3c2410fb_info, fb);
}

/* s3c2410fb_set_lcdaddr
 *
 * initialise lcd controller address pointers
*/

static void s3c2410fb_set_lcdaddr(struct s3c2410fb_info *fbi)
{
	struct fb_var_screeninfo *var = &fbi->fb.var;
	unsigned long saddr1, saddr2, saddr3;

	saddr1  = fbi->fb.fix.smem_start >> 1;
	saddr2  = fbi->fb.fix.smem_start;
	saddr2 += (var->xres * var->yres * var->bits_per_pixel)/8;
	saddr2>>= 1;

	saddr3 =  S3C2410_OFFSIZE(0) | S3C2410_PAGEWIDTH(var->xres);

	gprintk("LCDSADDR1 = 0x%08lx\n", saddr1);
	gprintk("LCDSADDR2 = 0x%08lx\n", saddr2);
	gprintk("LCDSADDR3 = 0x%08lx\n", saddr3);

	writel(saddr1, S3C2410_LCDSADDR1);
	writel(saddr2, S3C2410_LCDSADDR2);
	writel(saddr3, S3C2410_LCDSADDR3);
}

/* s3c2410fb_calc_pixclk()
 *
 * calculate divisor for clk->pixclk
*/
static unsigned int s3c2410fb_calc_pixclk(struct s3c2410fb_info *fbi,
					  unsigned long pixclk)
{
	unsigned long clk = clk_get_rate(fbi->clk); // hclk get
	unsigned long long div;

	div = (unsigned long long)clk / pixclk;
	return div;
}

/*
 *	s3c2410fb_check_var():
 *	Get the video params out of 'var'. If a value doesn't fit, round it up,
 *	if it's too big, return -EINVAL.
 *
 */
static int s3c2410fb_check_var(struct fb_var_screeninfo *var,
			       struct fb_info *info)
{
	struct s3c2410fb_info *fbi = fb_to_s3cfb(info);

	gprintk("check_var(var=%p, info=%p)\n", var, info);

	/* validate x/y resolution */

	if (var->yres > fbi->mach_info->yres.max)
		var->yres = fbi->mach_info->yres.max;
	else if (var->yres < fbi->mach_info->yres.min)
		var->yres = fbi->mach_info->yres.min;

	if (var->xres > fbi->mach_info->xres.max)
		var->yres = fbi->mach_info->xres.max;
	else if (var->xres < fbi->mach_info->xres.min)
		var->xres = fbi->mach_info->xres.min;

	/* validate bpp */

	if (var->bits_per_pixel > fbi->mach_info->bpp.max)
		var->bits_per_pixel = fbi->mach_info->bpp.max;
	else if (var->bits_per_pixel < fbi->mach_info->bpp.min)
		var->bits_per_pixel = fbi->mach_info->bpp.min;

	/* set r/g/b positions */

	if (var->bits_per_pixel == 16) {
		var->red.offset		= 11;
		var->green.offset	= 5;
		var->blue.offset	= 0;
		var->red.length		= 5;
		var->green.length	= 6;
		var->blue.length	= 5;
		var->transp.length	= 0;
	} else {
		var->red.length		= 8;
		var->red.offset		= 0;
		var->green.length	= 0;
		var->green.offset	= 8;
		var->blue.length	= 8;
		var->blue.offset	= 0;
		var->transp.length	= 0;
	}

	return 0;
}

/* s3c2410fb_activate_var
 *
 * activate (set) the controller from the given framebuffer
 * information
*/

static int s3c2410fb_activate_var(struct s3c2410fb_info *fbi,
				  struct fb_var_screeninfo *var)
{
	fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_MODEMASK;

	gprintk("%s: var->xres  = %d\n", __FUNCTION__, var->xres);
	gprintk("%s: var->yres  = %d\n", __FUNCTION__, var->yres);
	gprintk("%s: var->bpp   = %d\n", __FUNCTION__, var->bits_per_pixel);

	switch (var->bits_per_pixel) {
	case 1:
		fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT1BPP;
		break;
	case 2:
		fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT2BPP;
		break;
	case 4:
		fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT4BPP;
		break;
	case 8:
		fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT8BPP;
		break;
	case 16:
		fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT16BPP;
		break;

	default:
		/* invalid pixel depth */
		dev_err(fbi->dev, "invalid bpp %d\n", var->bits_per_pixel);
	}

	/* check to see if we need to update sync/borders */

	if (!fbi->mach_info->fixed_syncs) {
		gprintk("setting vert: up=%d, low=%d, sync=%d\n",
			var->upper_margin, var->lower_margin,
			var->vsync_len);

		gprintk("setting horz: lft=%d, rt=%d, sync=%d\n",
			var->left_margin, var->right_margin,
			var->hsync_len);

		fbi->regs.lcdcon2 =
			S3C2410_LCDCON2_VBPD(var->upper_margin - 1) |
			S3C2410_LCDCON2_VFPD(var->lower_margin - 1) |
			S3C2410_LCDCON2_VSPW(var->vsync_len - 1);

		fbi->regs.lcdcon3 =
			S3C2410_LCDCON3_HBPD(var->right_margin - 1) |
			S3C2410_LCDCON3_HFPD(var->left_margin - 1);

		fbi->regs.lcdcon4 &= ~S3C2410_LCDCON4_HSPW(0xff);
		fbi->regs.lcdcon4 |=  S3C2410_LCDCON4_HSPW(var->hsync_len - 1);
	}

	/* update X/Y info */

	fbi->regs.lcdcon2 &= ~S3C2410_LCDCON2_LINEVAL(0x3ff);
	fbi->regs.lcdcon2 |=  S3C2410_LCDCON2_LINEVAL(var->yres - 1);

	fbi->regs.lcdcon3 &= ~S3C2410_LCDCON3_HOZVAL(0x7ff);
	fbi->regs.lcdcon3 |=  S3C2410_LCDCON3_HOZVAL(var->xres - 1);

	gprintk("%s: pixclock = %u\n", __FUNCTION__, var->pixclock);

	if (var->pixclock > 0) {
		int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock);

		clkdiv = (clkdiv / 2) -1;
		if (clkdiv < 0)
			clkdiv = 0;


		gprintk("CLKVAL = %d\n", clkdiv);

		fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_CLKVAL(0x3ff);
		fbi->regs.lcdcon1 |=  S3C2410_LCDCON1_CLKVAL(clkdiv);
	}

	/* write new registers */

	gprintk("new register set:\n");
	gprintk("lcdcon[1] = 0x%08lx\n", fbi->regs.lcdcon1);
	gprintk("lcdcon[2] = 0x%08lx\n", fbi->regs.lcdcon2);
	gprintk("lcdcon[3] = 0x%08lx\n", fbi->regs.lcdcon3);
	gprintk("lcdcon[4] = 0x%08lx\n", fbi->regs.lcdcon4);
	gprintk("lcdcon[5] = 0x%08lx\n", fbi->regs.lcdcon5);

	writel(fbi->regs.lcdcon1 & ~S3C2410_LCDCON1_ENVID, S3C2410_LCDCON1);
	writel(fbi->regs.lcdcon2, S3C2410_LCDCON2);
	writel(fbi->regs.lcdcon3, S3C2410_LCDCON3);
	writel(fbi->regs.lcdcon4, S3C2410_LCDCON4);
	writel(fbi->regs.lcdcon5, S3C2410_LCDCON5);

	/* set lcd address pointers */
	s3c2410fb_set_lcdaddr(fbi);

	writel(fbi->regs.lcdcon1, S3C2410_LCDCON1);

	return 0;
}


/*
 *      s3c2410fb_set_par - Optional function. Alters the hardware state.
 *      @info: frame buffer structure that represents a single frame buffer
 *
 */
static int s3c2410fb_set_par(struct fb_info *info)
{
	struct s3c2410fb_info *fbi = (struct s3c2410fb_info *)info;
	struct fb_var_screeninfo *var = &info->var;

	if (var->bits_per_pixel == 16)
		fbi->fb.fix.visual = FB_VISUAL_TRUECOLOR;
	else
		fbi->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;

	fbi->fb.fix.line_length     = (var->width*var->bits_per_pixel)/8;


	/* activate this new configuration */

	s3c2410fb_activate_var(fbi, var);
	return 0;
}

static void schedule_palette_update(struct s3c2410fb_info *fbi,
				    unsigned int regno, unsigned int val)
{
	unsigned long flags;
	unsigned long irqen;

	local_irq_save(flags);

	fbi->palette_buffer[regno] = val;

	if (!fbi->palette_ready) {
		fbi->palette_ready = 1;

		/* enable IRQ */
		irqen = readl(S3C2410_LCDINTMSK);
		irqen &= ~S3C2410_LCDINT_FRSYNC;
		writel(irqen, S3C2410_LCDINTMSK);
	}

	local_irq_restore(flags);
}

/* from pxafb.c */
static inline unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf)
{
	chan &= 0xffff;
	chan >>= 16 - bf->length;
	return chan << bf->offset;
}

static int s3c2410fb_setcolreg(unsigned regno,
			       unsigned red, unsigned green, unsigned blue,
			       unsigned transp, struct fb_info *info)
{
	struct s3c2410fb_info *fbi = (struct s3c2410fb_info *)info;
	unsigned int val;

	switch (fbi->fb.fix.visual) {
	case FB_VISUAL_TRUECOLOR:
		/* true-colour, use pseuo-palette */

		if (regno < 16) {
			u32 *pal = fbi->fb.pseudo_palette;

			val  = chan_to_field(red,   &fbi->fb.var.red);
			val |= chan_to_field(green, &fbi->fb.var.green);
			val |= chan_to_field(blue,  &fbi->fb.var.blue);

			pal[regno] = val;
		}

	case FB_VISUAL_STATIC_PSEUDOCOLOR:
	case FB_VISUAL_PSEUDOCOLOR:
		if (regno < 256) {
			/* currently assume RGB 5-6-5 mode */

			val  = ((red   >>  0) & 0xf800);
			val |= ((green >>  5) & 0x07e0);
			val |= ((blue  >> 11) & 0x001f);

			writel(val, S3C2410_TFTPAL(regno));
			schedule_palette_update(fbi, regno, val);
		}

		break;

	default:
		return 1;   /* unknown type */
	}

	return 0;
}


/**
 *	s3c2410fb_pan_display
 *	@var: frame buffer variable screen structure
 *	@info: frame buffer structure that represents a single frame buffer
 *
 *	Pan (or wrap, depending on the `vmode' field) the display using the

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
久久品道一品道久久精品| 国产精品色哟哟网站| 成人综合在线观看| 亚洲www啪成人一区二区麻豆| 日韩精品最新网址| 欧美在线免费播放| 国产高清不卡一区| 免费视频最近日韩| 一区二区三区欧美久久| 26uuu亚洲综合色欧美| 欧美日韩一区二区电影| 成人午夜私人影院| 国模一区二区三区白浆| 日韩主播视频在线| 亚洲网友自拍偷拍| 中文字幕一区免费在线观看| 久久夜色精品一区| 日韩免费在线观看| 欧美男女性生活在线直播观看| 不卡av免费在线观看| 国产精品18久久久| 狠狠色狠狠色综合日日91app| 亚洲成av人片在线观看无码| 亚洲日本va午夜在线电影| 国产日韩高清在线| 国产亚洲一区字幕| 精品国产a毛片| 日韩精品一区二区三区四区视频 | 日本久久一区二区| 成人污视频在线观看| 国产在线不卡视频| 韩国精品主播一区二区在线观看 | 亚洲日本va午夜在线影院| 久久久久久久综合色一本| 欧美不卡一区二区三区| 欧美成人性福生活免费看| 日韩一区二区三区视频在线| 制服视频三区第一页精品| 欧美日本精品一区二区三区| 欧美日韩夫妻久久| 欧美一区二区视频网站| 欧美一区三区二区| 欧美大片国产精品| 亚洲精品一线二线三线无人区| 欧美成人r级一区二区三区| 91精品国产乱码| 日韩精品一区二区三区四区视频| 3d成人h动漫网站入口| 欧美一区三区二区| 久久夜色精品一区| 国产免费成人在线视频| 国产精品久久久久久久久久免费看| 国产欧美日韩一区二区三区在线观看 | av男人天堂一区| 91影院在线观看| 欧美偷拍一区二区| 日韩三级视频中文字幕| 久久久99免费| 国产精品免费观看视频| 亚洲日穴在线视频| 日韩国产成人精品| 国产乱子轮精品视频| 成人手机在线视频| 在线视频综合导航| 91麻豆精品国产91久久久资源速度 | 亚洲久本草在线中文字幕| 亚洲欧美色图小说| 日韩精品免费视频人成| 韩国在线一区二区| 99久久国产免费看| 欧美久久久影院| 国产日韩欧美制服另类| 亚洲精品视频自拍| 美女看a上一区| 成人国产精品免费| 666欧美在线视频| 国产三级精品三级| 亚洲国产欧美日韩另类综合| 裸体在线国模精品偷拍| 成人国产精品免费| 日韩视频国产视频| 综合色天天鬼久久鬼色| 免费成人在线播放| 色综合天天综合网天天看片| 日韩欧美中文字幕精品| 亚洲欧洲韩国日本视频| 蜜臀久久99精品久久久画质超高清| 日韩精品中文字幕在线不卡尤物| 国产精品久久久久久久久免费樱桃| 亚洲一线二线三线久久久| 国精产品一区一区三区mba桃花 | 成人h动漫精品一区二| 欧美精品在欧美一区二区少妇| 国产色综合一区| 日日夜夜免费精品视频| 99久久久无码国产精品| 日韩视频免费观看高清完整版 | 日韩不卡免费视频| 99精品黄色片免费大全| 精品99999| 五月婷婷综合在线| 99久久国产免费看| 久久精品一区八戒影视| 爽好多水快深点欧美视频| av色综合久久天堂av综合| 欧美成人video| 亚洲成国产人片在线观看| 99国产精品久久久| 欧美激情一二三区| 久久99国产精品成人| 欧美年轻男男videosbes| 亚洲天堂免费在线观看视频| 国产大陆a不卡| 欧美va亚洲va国产综合| 午夜电影网一区| 在线观看免费亚洲| 亚洲免费av高清| www.亚洲精品| 国产精品青草综合久久久久99| 国产揄拍国内精品对白| 欧美刺激脚交jootjob| 免费观看在线色综合| 欧美疯狂性受xxxxx喷水图片| 玉足女爽爽91| 91久久精品午夜一区二区| 国产精品久久看| av亚洲精华国产精华精| 国产欧美一区二区三区鸳鸯浴| 国产乱码精品一区二区三区五月婷 | 国产精品亚洲成人| 久久久午夜精品理论片中文字幕| 精品制服美女丁香| 精品福利一二区| 国产一区二区成人久久免费影院 | 国内成+人亚洲+欧美+综合在线| 日韩视频免费直播| 精品一区二区三区视频| 日韩免费观看高清完整版 | 伊人夜夜躁av伊人久久| 91高清视频免费看| 亚洲成人免费电影| 欧美一级xxx| 美美哒免费高清在线观看视频一区二区 | 欧美mv日韩mv国产网站app| 美国十次了思思久久精品导航| 日韩免费视频一区二区| 狠狠色丁香婷综合久久| 国产人久久人人人人爽| 国产亚洲女人久久久久毛片| 国产成人午夜精品影院观看视频| 欧美国产一区二区| 97精品国产露脸对白| 亚洲国产精品久久一线不卡| 91精品久久久久久久99蜜桃| 久久 天天综合| 国产精品久久久久久久久晋中| 91香蕉国产在线观看软件| 亚洲国产美女搞黄色| 日韩一区二区三区电影在线观看 | 蜜桃一区二区三区在线| 精品国产亚洲在线| av中文字幕一区| 亚洲成年人影院| 精品不卡在线视频| 成人毛片视频在线观看| 亚洲综合丁香婷婷六月香| 日韩一区二区三区免费看| 国产一区二区网址| 亚洲伦理在线精品| 欧美哺乳videos| 99视频一区二区| 日韩电影免费一区| 国产精品欧美极品| 在线观看91av| 成人深夜福利app| 日韩电影在线观看网站| 欧美激情一区二区三区四区| 欧美三级在线视频| 国产成人综合在线| 午夜精彩视频在线观看不卡| 国产亚洲综合av| 欧美日韩一区二区在线观看 | 成人avav在线| 日韩av电影免费观看高清完整版| 国产女主播在线一区二区| 欧美日韩综合一区| 成人综合日日夜夜| 日韩国产欧美三级| 椎名由奈av一区二区三区| 日韩欧美二区三区| 在线观看亚洲一区| 国产精品2024| 强制捆绑调教一区二区| 亚洲丝袜精品丝袜在线| 久久综合av免费| 欧美一区二区视频在线观看2020| 91网站视频在线观看| 国产成人夜色高潮福利影视| 日本欧美一区二区三区乱码| 最新中文字幕一区二区三区 |