📄 at91_lcd.c
字号:
#include <linux/module.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/ioport.h>#include <asm/io.h>#include <asm/uaccess.h>#ifdef CONFIG_DEVFS_FS#include <linux/devfs_fs_kernel.h>#endif#include "at91_lcd.h"static int at91_lcd_base;static int at91_lcd_major;#ifdef CONFIG_DEVFS_FSstatic devfs_handle_t lcd_device; #endif#define DELAY_TIME 20static void at91_config_pio_lcd(void){ /* disable LCD_CS_OUT I/O */ AT91_SYS->PIOC_PDR = LCD_CS_OUT; /* enable LCD_RS_OUT & LCD_BACK_LIGHT I/O */ AT91_SYS->PIOC_PER = LCD_RS_OUT | LCD_BACK_LIGHT | LCD_RW_OUT; /* enable LCD_RS_OUT & LCD_BACK_LIGHT output */ AT91_SYS->PIOC_OER = LCD_RS_OUT | LCD_BACK_LIGHT | LCD_RW_OUT; /* set the bus interface characteristics */// AT91_SYS->EBI_SMC2_CSR[6] = (LCD_RWH | LCD_RWS | LCD_DBW | LCD_TDF | LCD_WSEN | LCD_NWS); AT91_SYS->EBI_SMC2_CSR[3] = (LCD_RWH | LCD_RWS | LCD_DBW | LCD_TDF | LCD_WSEN | LCD_NWS); AT91_SYS->PIOC_SODR = LCD_BACK_LIGHT; }static unsigned char lcd_get_status(void){ AT91_SYS->PIOC_CODR = LCD_RS_OUT; /* set LCD_RS_OUT low D/nC =0 */ AT91_SYS->PIOC_SODR = LCD_RW_OUT; /* set LCD_RW_OUT low R/nW =1 READ*/ return inb(at91_lcd_base); udelay(DELAY_TIME); }static void lcd_write_control(char data){ while((lcd_get_status() & 0x80) != 0); AT91_SYS->PIOC_CODR = LCD_RS_OUT; /* set LCD_RS_OUT low D/nC =0 COMMAND*/ AT91_SYS->PIOC_CODR = LCD_RW_OUT; /* set LCD_RW_OUT low R/nW =0 WRITE */ outb(data, at91_lcd_base); udelay(DELAY_TIME); }static void lcd_write_data(char data){ /*printk("write data 0x%2X to LCD controllor\n\r", data);*/ while((lcd_get_status() & 0x80) != 0); AT91_SYS->PIOC_SODR = LCD_RS_OUT; /* set LCD_RS_OUT high D/nC =1 DATA */ AT91_SYS->PIOC_CODR = LCD_RW_OUT; /* set LCD_RW_OUT low R/nW =0 WRITE */ outb(data, at91_lcd_base); udelay(DELAY_TIME); }static void lcd_power_on(void){}static void lcd_power_off(void){// lcd_write_control(LCD_PWR_CTR);}/*static void lcd_cursor_column(char column){ //printk("set cursor x to %d\n\r", column); lcd_write_control(LCD_SET_COL1 | (column >> 4)); lcd_write_control(LCD_SET_COL2 | (column & 0x0f));}static void lcd_cursor_row(char row){ //printk("set cursor y to %d\n\r", row); lcd_write_control(LCD_SET_PAGE | row);}*/static void lcd_cls(void)//清屏{ lcd_write_control(0x01);}static int lcd_open(struct inode *inode, struct file *filp){ int i,j; MOD_INC_USE_COUNT; return 0;} static int lcd_release(struct inode *inode, struct file *filp){ MOD_DEC_USE_COUNT; return 0;}static int lcd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg){ switch(cmd) { case LCD_POWER: {/* int data; if(get_user(data, (int *)arg)) return -EFAULT; if(data) lcd_power_on(); else lcd_power_off();*/ break; } case LCD_DISPLAY: {// int data;// if(get_user(data, (int *)arg)) return -EFAULT; /*printk("LCD display is turned %s\n\r", data?"on":"off");*/// if(!data) lcd_write_control(LCD_DSP_CTR);// else lcd_write_control(LCD_DSP_CTR | 0x01); break; } case LCD_BACKLIGHT: { char data; if(get_user(data, (char *)arg)) return -EFAULT; if(data) AT91_SYS->PIOC_SODR = LCD_BACK_LIGHT; else AT91_SYS->PIOC_CODR = LCD_BACK_LIGHT; return 0; } case LCD_CLEAR: lcd_cls(); break; case LCD_CURSOR_X: {/* int data; if(get_user(data, (int *)arg)) return -EFAULT; lcd_cursor_column((char)data );*/ break; } case LCD_CURSOR_Y: {/* int data; if(get_user(data, (int *)arg)) return -EFAULT; lcd_cursor_row((char)data);*/ break; } case LCD_CURSOR_XY: { int data;// if(get_user(data, (int *)arg)) return -EFAULT; get_user(data, (int *)arg); lcd_write_control((char)data); break; } case LCD_WRITE: { char data;// if(get_user(data, (char *)arg)) return -EFAULT; get_user(data, (char *)arg); lcd_write_data(data); break; } default:// return -EINVAL; break; } return 0;}static struct file_operations lcd_fops ={ owner: THIS_MODULE, open: lcd_open, release: lcd_release, ioctl: lcd_ioctl};static int __init at91_lcd_init(void){ int i,j; printk(KERN_INFO "lcd: S6B0719 160x105 LCD pannel, ");#ifdef CONFIG_DEVFS_FS at91_lcd_major = devfs_register_chrdev(0, "lcd", &lcd_fops);#else at91_lcd_major = register_chrdev(0, "lcd", &lcd_fops);#endif if(at91_lcd_major < 0) { printk(KERN_WARNING "lcd: unable to get major for lcd driver\n"); return at91_lcd_major; } #ifdef CONFIG_DEVFS_FS lcd_device = devfs_register(NULL, "lcd", DEVFS_FL_DEFAULT, at91_lcd_major, 0, S_IFCHR | S_IRUGO | S_IWUGO, &lcd_fops, NULL);#endif at91_lcd_base = (unsigned long) ioremap(LCD_ACCESS_ADDR, SZ_1K); if(!at91_lcd_base) { printk("ioremap AT91 LCD failed\n"); return -EIO; } at91_config_pio_lcd(); printk("lcd 4*16 char driver loading\n"); for(i=3;i>0;i--)
{
lcd_write_control(0x30); j=j; } lcd_write_control(0x38); lcd_write_control(0x0c); lcd_write_control(0x06); lcd_write_control(0x02); lcd_write_control(0x01); for(i=255;i>0;i--)j=j; lcd_write_control(0x40); lcd_write_data(0); lcd_write_data(0); lcd_write_data(0); lcd_write_data(0); lcd_write_data(0); lcd_write_data(0x1f); lcd_write_data(0x0e); lcd_write_data(4); lcd_write_data(4); lcd_write_data(0xe); lcd_write_data(0x1f); lcd_write_data(0); lcd_write_data(0); lcd_write_data(0); lcd_write_data(0); lcd_write_data(0); lcd_write_control(0x80); //display "OK!" lcd_write_data('O'); udelay(DELAY_TIME); lcd_write_control(0x81); lcd_write_data('K'); udelay(DELAY_TIME); lcd_write_control(0x82); lcd_write_data('!'); udelay(DELAY_TIME); lcd_write_control(0x83); lcd_write_data(' '); udelay(DELAY_TIME); printk("lcd 4*16 char driver loaded \n"); return 0;} static void __exit at91_lcd_exit(void){#ifdef CONFIG_DEVFS_FS devfs_unregister(lcd_device); if(devfs_unregister_chrdev(at91_lcd_major, "lcd")) {#else if(unregister_chrdev(at91_lcd_major, "lcd")) {#endif printk(KERN_ERR "lcd: unable to release major %d for LCD driver\n", at91_lcd_major); }}module_init(at91_lcd_init);module_exit(at91_lcd_exit);MODULE_LICENSE("GPL");MODULE_DESCRIPTION("LCD driver for net tester");MODULE_AUTHOR("Jim Lao");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -