?? ili9325.c
字號:
/* * drivers/video/ili932x.c * * Author liulf, liulf@ihep.ac.cn * Copyright (C) 2008 Changsha Wasion Meters Group * * The source code in this file can be freely used, adapted, * and redistributed in source or binary form, so long as an * acknowledgment appears in derived source files. The citation * should list that the code comes from the book "Linux Device * Drivers" by Alessandro Rubini and Jonathan Corbet, published * by O'Reilly & Associates. No warranty is attached; * we cannot take responsibility for errors or fitness for use. */#include <linux/clk.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/init.h>#include <linux/mutex.h>#include <linux/string.h>#include <linux/clk.h>#include <linux/ioport.h>#include <linux/slab.h> /* kmalloc() */#include <linux/fs.h> /* everything... */#include <linux/types.h> /* size_t */#include <linux/fcntl.h> /* O_ACCMODE */#include <linux/cdev.h> /*cdev...*/#include <linux/interrupt.h> /*request_irq()...*/#include <asm/irq.h> /*irq no.,etc.*/#include <linux/irq.h>#include <asm/io.h> /*writel(),readl()...*/#include <asm/system.h> /* cli(), *_flags */#include <linux/wait.h> /*wake_up_interrupkbble()...*/#include <linux/delay.h> /*udelay()*/#include <linux/device.h> /*class_create(),class_device_create()...*/#include <asm/errno.h>#include <mach/hardware.h>#include <asm/uaccess.h>#include <linux/delay.h>#include <asm/mach/arch.h>#include <asm/mach/map.h>#include <linux/platform_device.h>#include <linux/proc_fs.h> /*proc fs*/#include <mach/board.h>#include <mach/gpio.h>#include <mach/at91sam9260.h>#include <mach/at91sam9260_matrix.h>#include <linux/init.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/cdev.h>#include <linux/delay.h>#include <linux/device.h>#include <linux/jiffies.h>#include <linux/mutex.h>#include <linux/uaccess.h>#include <linux/vmalloc.h>#include <linux/workqueue.h>#include "ili932x.h"#include <linux/wfos_debug.h>struct ili932x_device { void __iomem *membase;};/* * Module Parameters */static unsigned int ili932x_rate = CONFIG_ILI932X_RATE;module_param(ili932x_rate, uint, S_IRUGO);MODULE_PARM_DESC(ili932x_rate, "Refresh rate (hertzs)");unsigned int ili932x_getrate(void){ return ili932x_rate;}/* * Update work */struct ili932x_device *lcd_ili932x = NULL;static u16 ili932x_reg_cache[ILI9325_TIMING_CTRL_3 + 1];unsigned char *ili932x_buffer;static unsigned char *ili932x_cache;static DEFINE_MUTEX(ili932x_mutex);static unsigned char ili932x_updating;static void ili932x_update(struct work_struct *delayed_work);static struct workqueue_struct *ili932x_workqueue;static DECLARE_DELAYED_WORK(ili932x_work, ili932x_update);static void ili932x_queue(void){ queue_delayed_work(ili932x_workqueue, &ili932x_work, HZ / ili932x_rate);}unsigned char ili932x_enable(void){ unsigned char ret; mutex_lock(&ili932x_mutex); if (!ili932x_updating) { ili932x_updating = 1; ili932x_queue(); ret = 0; } else ret = 1; mutex_unlock(&ili932x_mutex); return ret;}void ili932x_disable(void){ mutex_lock(&ili932x_mutex); if (ili932x_updating) { ili932x_updating = 0; cancel_delayed_work(&ili932x_work); flush_workqueue(ili932x_workqueue); } mutex_unlock(&ili932x_mutex);}unsigned char ili932x_isenabled(void){ return ili932x_updating;}static inline void ili9325_write_pixel(struct ili932x_device *dev, u32 pixel){#if ILI9325_BPP == 32 u8 r, g, b; u32 color = 0; /* 24/32-bit colors to 18-bit colors.*/ b = (pixel & 0xff) >> 2; g = ((pixel >> 8 ) & 0xff) >> 2; r = ((pixel >> 16) & 0xff ) >> 2; color = (r << 12) | (g << 6) | (b << 0); writew((color >> 2) & 0xffff, dev->membase); writew((b & 0x3) << 14 , dev->membase); #elif ILI9325_BPP == 16 writew(pixel & 0xffff, dev->membase); #endif return;}static inline int ili932x_write_reg(struct ili932x_device *dev, u8 reg, u16 data){ void __iomem *index = dev->membase; BUG_ON(reg > ILI9325_TIMING_CTRL_3); at91_set_gpio_output(AT91_PIN_PB24, 0); /* RS = 0 */ //udelay(50); writew(reg, index); at91_set_gpio_output(AT91_PIN_PB24, 1); /* RS = 1 */ //udelay(50); //writew(data, index); writew(data, index); ili932x_reg_cache[reg] = data; return 0;}static inline int ili932x_read_reg(struct ili932x_device *dev, u8 reg){ void __iomem *index = dev->membase; void __iomem *data_base = dev->membase; if (reg > ILI9325_DRV_CODE) { return ili932x_reg_cache[reg]; } else { at91_set_gpio_output(AT91_PIN_PB24, 0); /* RS = 0 */ udelay(50); writew(reg, index); at91_set_gpio_output(AT91_PIN_PB24, 1); /* RS = 1 */ udelay(50); //return readw(data_base); return readw(data_base); }}static void ili932x_reset(void){ at91_set_gpio_output(ILI9325_LCD_RST, 0); msleep(300); at91_set_gpio_output(ILI9325_LCD_RST, 1); msleep(100); return;}/* Power On sequence */static void ili9325_pow_on(struct ili932x_device *dev){ ili932x_write_reg(dev, ILI9325_POW_CTRL_1, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ ili932x_write_reg(dev, ILI9325_POW_CTRL_2, 0x0007); /* DC1[2:0], DC0[2:0], VC[2:0] */ ili932x_write_reg(dev, ILI9325_POW_CTRL_3, 0x0000); /* VREG1OUT voltage */ ili932x_write_reg(dev, ILI9325_POW_CTRL_4, 0x0000); /* VDV[4:0] for VCOM amplitude */ msleep(200); /* Dis-charge capacitor power voltage */ ili932x_write_reg(dev, ILI9325_POW_CTRL_1, 0x1690); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ ili932x_write_reg(dev, ILI9325_POW_CTRL_2, 0x0227); /* R11h=0x0221 at VCI=3.3V, DC1[2:0], DC0[2:0], VC[2:0] */ msleep(50); ili932x_write_reg(dev, ILI9325_POW_CTRL_3, 0x001D); /* External reference voltage= Vci */ msleep(50); ili932x_write_reg(dev, ILI9325_POW_CTRL_4, 0x0800); /* R13=1D00 when R12=009D;VDV[4:0] for VCOM amplitude */ ili932x_write_reg(dev, ILI9325_POW_CTRL_7, 0x0012); /* R29=0013 when R12=009D;VCM[5:0] for VCOMH */ ili932x_write_reg(dev, ILI9325_FRM_RATE_COLOR, 0x000B); /* Frame Rate = 70Hz */ msleep(50); return;}/* Adjust the Gamma Curve */static void ili9325_gamma_adjust(struct ili932x_device *dev){ ili932x_write_reg(dev, ILI9325_GAMMA_CTRL_1, 0x0007); ili932x_write_reg(dev, ILI9325_GAMMA_CTRL_2, 0x0707); ili932x_write_reg(dev, ILI9325_GAMMA_CTRL_3, 0x0006); ili932x_write_reg(dev, ILI9325_GAMMA_CTRL_4, 0x0704); ili932x_write_reg(dev, ILI9325_GAMMA_CTRL_5, 0x1F04); ili932x_write_reg(dev, ILI9325_GAMMA_CTRL_6, 0x0004); ili932x_write_reg(dev, ILI9325_GAMMA_CTRL_7, 0x0000); ili932x_write_reg(dev, ILI9325_GAMMA_CTRL_8, 0x0706); ili932x_write_reg(dev, ILI9325_GAMMA_CTRL_9, 0x0701); ili932x_write_reg(dev, ILI9325_GAMMA_CTRL_10, 0x000F); return;}/* Partial Display Control */static void ili9325_par_dis_ctrl(struct ili932x_device *dev){ ili932x_write_reg(dev, ILI9325_PAR_IMG1_POS, 0); ili932x_write_reg(dev, ILI9325_PAR_IMG1_START, 0); ili932x_write_reg(dev, ILI9325_PAR_IMG1_END, 0); ili932x_write_reg(dev, ILI9325_PAR_IMG2_POS, 0); ili932x_write_reg(dev, ILI9325_PAR_IMG2_START, 0); ili932x_write_reg(dev, ILI9325_PAR_IMG2_END, 0); return;}/* Panel Control */static void ili9325_pan_ctrl(struct ili932x_device *dev){ ili932x_write_reg(dev, ILI9325_PAN_CTRL_1, 0x0010); ili932x_write_reg(dev, ILI9325_PAN_CTRL_2, 0x0000); ili932x_write_reg(dev, ILI9325_PAN_CTRL_3, 0x0003); ili932x_write_reg(dev, ILI9325_PAN_CTRL_4, 0x0110); ili932x_write_reg(dev, ILI9325_PAN_CTRL_5, 0x0000); ili932x_write_reg(dev, ILI9325_PAN_CTRL_6, 0x0000); ili932x_write_reg(dev, ILI9325_DIS_CTRL_1, 0x0133); /* 262K color and display ON */ return;}/* Start Initial Sequence */static void ili9325_chip_init(struct ili932x_device *dev){ printk("ili9325_chip_init.\n"); ili932x_write_reg(dev, ILI9325_TIMING_CTRL_1, 0x3008); /* Set internal timing*/ ili932x_write_reg(dev, ILI9325_TIMING_CTRL_2, 0x0012); /* Set internal timing*/ ili932x_write_reg(dev, ILI9325_TIMING_CTRL_3, 0x1231); /* Set internal timing*/ ili932x_write_reg(dev, ILI9325_DRV_OUTPUT_CTRL_1, 0x0100); /* set SS and SM bit */ ili932x_write_reg(dev, ILI9325_LCD_DRV_CTRL, 0x0700); /* set 1 line inversion */ #if ILI9325_BPP == 16 printk("ili9325_chip init bpp16.\n"); ili932x_write_reg(dev, ILI9325_ENTRY_MOD, 0x1030); /* 16bit mode, set GRAM write direction and BGR=1. */#elif ILI9325_BPP == 32 ili932x_write_reg(dev, ILI9325_ENTRY_MOD, 0x9030); /* 18bit mode, set GRAM write direction and BGR=1. */#endif ili932x_write_reg(dev, ILI9325_RESIZE_CTRL, 0x0000); /* Resize register. */ ili932x_write_reg(dev, ILI9325_DIS_CTRL_2, 0x0207); /* set the back porch and front porch. */ ili932x_write_reg(dev, ILI9325_DIS_CTRL_3, 0x0000); /* set non-display area refresh cycle ISC[3:0]. */ ili932x_write_reg(dev, ILI9325_DIS_CTRL_4, 0x0000); /* FMARK function. */ ili932x_write_reg(dev, ILI9325_RGB_CTRL_1, 0x0000); /* RGB interface setting. */ ili932x_write_reg(dev, ILI9325_FRAME_MARKER_POS, 0x0000); /* Frame marker Position. */ ili932x_write_reg(dev, ILI9325_RGB_CTRL_2, 0x0000); /* RGB interface polarity. */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -