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

📄 omap_disp_out.c

📁 omap3 linux 2.6 用nocc去除了冗余代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * drivers/video/omap/omap2_disp_out.c * * Driver for LCD and TV output on OMAP24xx SDPs *	- Tested on OMAP2420 H4 * * Copyright (C) 2005-2006 Texas Instruments, Inc. * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any * kind, whether express or implied. * * History: * 30-Mar-2006	Khasim	Added LCD data lines 18/16 support * 15-Apr-2006	Khasim	Modified proc fs to sysfs * 20-Apr-2006	Khasim	Modified PM/DPM support for Mobi-Linux */#include <linux/module.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/ioport.h>#include <linux/types.h>#include <linux/init.h>#include <linux/interrupt.h>#include <linux/i2c.h>#include <linux/proc_fs.h>#include <linux/fb.h>#include <linux/delay.h>#include <asm/hardware.h>#include <asm/uaccess.h>#include <asm/delay.h>#include <linux/delay.h>#include <asm/arch/display.h>#include <asm/arch/gpio.h>#include <asm/arch/clock.h>#include <asm/arch/twl4030.h>#include <linux/workqueue.h>#include <asm/arch/power_companion.h>#include <linux/notifier.h>#include <linux/pm.h>#include <linux/platform_device.h>#include "omap_fb.h"#define DRIVER			"omap2_disp_out"#define	DRIVER_DESC		"OMAP Display output driver"#define OMAP2_LCD_DRIVER	"omap2_lcd"#define OMAP2_TV_DRIVER		"omap2_tv"#define OMAP24xx_LCD_DEVICE		"omap2_lcd"#define OMAP24xx_TV_DEVICE		"omap2_tv"#define H4_LCD_XRES	 	1024 // 1024#define H4_LCD_YRES 		768 // 720#define H4_LCD_PIXCLOCK_MAX	41700 /* in pico seconds  */#define H4_LCD_PIXCLOCK_MIN	38000  /* in pico seconds */#define H4_TV_XRES		640#define H4_TV_YRES		480#define LCD_PANEL_ENABLE_GPIO 		28#define LCD_PANEL_BACKLIGHT_GPIO 	24#define CONFIG_OMAP2_LCD#define ENABLE_VDAC_DEDICATED		0x03#define ENABLE_VDAC_DEV_GRP             0x20	     #define ENABLE_VPLL2_DEDICATED		0x05#define ENABLE_VPLL2_DEV_GRP            0xE0#define CONFIG_OMAP2_TV#define MENELAUS_I2C_ADAP_ID		0#define CONFIG_TWL4030_CORE_T2#define CONFIG_I2C_TWL4030_COREextern int omap24xx_get_dss1_clock(void);extern ssize_t fb_out_show(struct class_device *cdev, char *buf);extern ssize_t fb_out_store(struct class_device *cdev, const char *buffer, size_t count);extern int fb_out_layer;extern int omap24xxfb_set_output_layer(int layer);extern int twl4030_request_gpio(int gpio);extern int twl4030_free_gpio(int gpio);extern int twl4030_set_gpio_dataout(int gpio, int enable);extern int twl4030_set_gpio_direction(int gpio, int is_input);extern int lpr_enabled;/*---------------------------------------------------------------------------*/static int lcd_in_use;static int lcd_backlight_state=1;static int previous_lcd_backlight_state=1;static void lcd_backlight_off(struct work_struct *work);static void lcd_backlight_on(struct work_struct *work);#define MOD_INC_USE_COUNT#define MOD_DEC_USE_COUNTDECLARE_WORK(lcd_bklight_on, lcd_backlight_on);DECLARE_WORK(lcd_bklight_off, lcd_backlight_off);static void lcd_panel_enable(struct work_struct *work);static void lcd_panel_disable(struct work_struct *work);DECLARE_WORK(lcd_panel_on, lcd_panel_enable);DECLARE_WORK(lcd_panel_off, lcd_panel_disable);static voidpower_lcd_backlight(int level){	switch (level) {		case LCD_OFF:			if(!in_interrupt())				lcd_backlight_off(NULL);			else				schedule_work(&lcd_bklight_off);			break;		default:			if(!in_interrupt())				lcd_backlight_on(NULL);			else				schedule_work(&lcd_bklight_on);			break;	}}static voidpower_lcd_panel(int level){	switch (level) {		case LCD_OFF:			if(!in_interrupt())				lcd_panel_disable(NULL);			else				schedule_work(&lcd_panel_off);			break;		default:			if(!in_interrupt())				lcd_panel_enable(NULL);			else				schedule_work(&lcd_panel_on);			break;	}}static voidlcd_panel_enable(struct work_struct *work){}voidomap2_dss_rgb_enable(void){	if(is_sil_rev_less_than(OMAP3430_REV_ES2_0)) {		if( 0 != twl4030_vaux3_ldo_use())			printk(KERN_WARNING "omap2_disp: twl4030_vaux3_ldo_use returns error \n");	}	else {		twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECIEVER,				ENABLE_VPLL2_DEDICATED,TWL4030_VPLL2_DEDICATED);		twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECIEVER,				ENABLE_VPLL2_DEV_GRP,TWL4030_VPLL2_DEV_GRP);		mdelay(4);	}}EXPORT_SYMBOL(omap2_dss_rgb_enable);static voidlcd_panel_disable(struct work_struct *work){}voidomap2_dss_rgb_disable(void){	if(is_sil_rev_less_than(OMAP3430_REV_ES2_0)) {		if( 0 != twl4030_vaux3_ldo_unuse())			printk(KERN_WARNING "omap2_disp: twl4030_vaux3_ldo_unuse returns error \n");	}	else {		twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECIEVER,				0x0,TWL4030_VPLL2_DEDICATED);		twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECIEVER,				0x0,TWL4030_VPLL2_DEV_GRP);			mdelay(4);      	}}EXPORT_SYMBOL(omap2_dss_rgb_disable);static voidlcd_backlight_on(struct work_struct *work){}static voidlcd_backlight_off(struct work_struct *work){}void enable_backlight(void){	/* If already enabled, return*/	if (lcd_in_use)		return;	if (previous_lcd_backlight_state == LCD_ON) {		power_lcd_backlight(LCD_ON);	}	lcd_in_use = 1;}EXPORT_SYMBOL(enable_backlight);void disable_backlight(void){	/* If LCD is already disabled, return*/	if (!lcd_in_use)		return;	previous_lcd_backlight_state = lcd_backlight_state;	power_lcd_backlight(LCD_OFF);	lcd_in_use = 0;}EXPORT_SYMBOL(disable_backlight);static int gpio_reserved = 0;int omap_lcd_init(struct omap_lcd_info *info){	u32	pixclock	= H4_LCD_PIXCLOCK_MAX,/* picoseconds */		left_margin	= 39,		/* pixclocks */		right_margin	= 45,		/* pixclocks */		upper_margin	= 1,		/* line clocks */		lower_margin	= 0,		/* line clocks */		hsync_len	= 3,		/* pixclocks */		vsync_len	= 2,		/* line clocks */		sync		= 1,		/* hsync & vsync polarity */		acb		= 0x28,		/* AC-bias pin frequency */		ipc		= 1,		/* Invert pixel clock */		onoff		= 1;		/* HSYNC/VSYNC Pixel clk Control*/	u32 clkdiv;	if (info) {		pixclock     = info->pixclock,		left_margin  = info->left_margin,		right_margin = info->right_margin,		upper_margin = info->upper_margin,		lower_margin = info->lower_margin,		hsync_len    = info->hsync_len,		vsync_len    = info->vsync_len,		sync         = info->sync,		acb          = info->acb,		ipc          = info->ipc,		onoff        = info->onoff;	}	if (gpio_reserved == 1)		goto bypass_gpio;bypass_gpio:	gpio_reserved = 1;	omap2_dss_rgb_enable();	omap2_disp_get_dss();	omap2_disp_set_panel_size(OMAP2_OUTPUT_LCD, H4_LCD_XRES, H4_LCD_YRES);	/* clkdiv = pixclock / (omap2 dss1 clock period) */	clkdiv = pixclock / (1000000000UL/omap24xx_get_dss1_clock());	clkdiv /= 1000;		omap2_disp_config_lcd(clkdiv,			      left_margin - 1,	// hbp			      right_margin - 1,	// hfp			      hsync_len - 1,	// hsw			      upper_margin,	// vbp			      lower_margin,	// vfp			      vsync_len - 1	// vsw			      );	omap2_disp_lcdcfg_polfreq(	sync,   // horizontal sync active low					sync,   // vertical sync active low					acb,    // ACB					ipc,    // IPC					onoff   // ONOFF				);																									 	omap2_disp_enable_output_dev(OMAP2_OUTPUT_LCD);	udelay(20);			enable_backlight();	power_lcd_panel(LCD_ON);	omap2_disp_put_dss();	printk(KERN_DEBUG DRIVER	       "LCD panel %dx%d\n", H4_LCD_XRES, H4_LCD_YRES);	return 0;}static intlcd_exit(void){	if (!lcd_in_use)		return 0;	omap2_disp_get_dss();	omap2_disp_disable_output_dev(OMAP2_OUTPUT_LCD);	omap2_disp_put_dss();	lcd_in_use = 0;		return 0;}/* ------------------------------------------------------------------------------ *//* Power and device Management */static int __initlcd_probe(struct platform_device *odev){	return omap_lcd_init(0);}static int lcd_suspend(struct platform_device *odev, pm_message_t state);static int lcd_resume(struct platform_device *odev);static struct platform_driver omap2_lcd_driver = {	.driver = {		.name   = OMAP2_LCD_DRIVER,	},	.probe          = lcd_probe,	.suspend        = lcd_suspend,	.resume         = lcd_resume,};static struct platform_device lcd_device = {        .name     = OMAP24xx_LCD_DEVICE,	.id    = 9,};static intlcd_suspend(struct platform_device *odev, pm_message_t state){		if (!lcd_in_use)		return 0;	disable_backlight();	omap2_dss_rgb_disable();		return 0;}static intlcd_resume(struct platform_device *odev){	if (lcd_in_use)		return 0;	omap2_dss_rgb_enable();	udelay(20);	enable_backlight();	return 0;}/*---------------------------------------------------------------------------*/static int tv_in_use;static void h4_i2c_tvout_off(struct work_struct *work);static void h4_i2c_tvout_on(struct work_struct *work);DECLARE_WORK(h4_tvout_on, h4_i2c_tvout_on);DECLARE_WORK(h4_tvout_off, h4_i2c_tvout_off);static voidpower_tv(int level){	switch(level) {		case TV_OFF:			if(!in_interrupt())				h4_i2c_tvout_off(NULL);			else				schedule_work(&h4_tvout_off);			break;		default:			if(!in_interrupt())				h4_i2c_tvout_on(NULL);			else				schedule_work(&h4_tvout_on);			break;	}}static voidh4_i2c_tvout_off(struct work_struct *work){	omap2_disp_get_all_clks();	omap2_disp_set_tvref(TVREF_OFF);	omap2_disp_put_all_clks();	omap2_disp_get_all_clks();	omap2_disp_set_tvref(TVREF_OFF);	omap2_disp_put_all_clks();	twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECIEVER,0x00,TWL4030_VDAC_DEDICATED);	twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECIEVER,0x00,TWL4030_VDAC_DEV_GRP);}static voidh4_i2c_tvout_on(struct work_struct *work){	omap2_disp_get_all_clks();	omap2_disp_set_tvref(TVREF_ON);	omap2_disp_put_all_clks();	omap2_disp_get_all_clks();	omap2_disp_set_tvref(TVREF_ON);	omap2_disp_put_all_clks();	twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECIEVER,			ENABLE_VDAC_DEDICATED,TWL4030_VDAC_DEDICATED);	twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECIEVER,			ENABLE_VDAC_DEV_GRP,TWL4030_VDAC_DEV_GRP);}static inttv_init(void){	omap2_disp_get_all_clks();	power_tv(TV_ON);	omap2_disp_set_tvstandard(NTSC_M);	omap2_disp_set_panel_size(OMAP2_OUTPUT_TV, H4_TV_XRES, H4_TV_YRES);	omap2_disp_enable_output_dev(OMAP2_OUTPUT_TV);	omap2_disp_put_all_clks();	printk(KERN_DEBUG DRIVER			"TV %dx%d interlaced\n", H4_TV_XRES, H4_TV_YRES);	tv_in_use = 1;	return 0;}static inttv_exit(void){

⌨️ 快捷键说明

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