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

📄 lcd.c

📁 用于Linux 2.4内核的LCD及键盘驱动
💻 C
字号:
#ifndef __KERNEL__#define __KERNEL__#endif#ifndef MODULE#define MODULE#endif#include <linux/kernel.h>#include <linux/module.h>#include <linux/init.h>#include <linux/delay.h>#include <linux/ioport.h>#include <asm/uaccess.h>#include <asm/io.h>#include <asm/8xx_immap.h>/** Header files for the charcater device */#include <linux/fs.h>#include <linux/wrapper.h>#include "lcd.h"#define DEBUGstatic volatile immap_t *immap;	/*define the struct immap_t pointer that represent memory map info */volatile unsigned long virt_base;/*lcd virtual address space base*/static int device_open_num = 0;	/*record numbers of lcd device opening by usr */static int Major;		/*the lcd device major number *//************************************************************************LCD hard interface functions*************************************************************************//**Initialize the driver -Register the character device*/static intlcd_init (void){  int ret;  init_mem ();  /*   *Register the character device -lcd   */  ret = register_chrdev (LCD_MAJOR, DEVICE_NAME, &lcd_ops);  /* register lcd device faild */  if (ret < 0)    {      iounmap ((void *) virt_base);      printk ("Lcd init_module register failed           with %d\n major number\n", Major);      return Major;    }  /*register successed */  Major = LCD_MAJOR;  printk ("Lcd register major number :%d successed\n", Major);  /*   *Lcd function initial   */  lcd_ctr_init ();  writeb (LED_OFF, (LED_ADDR - LCD_BASE) + virt_base);/*turn off led */  //writeb (LED_OFF, LED_ADDR); /*turn off led */  return SUCCESS;}static intinit_mem (void){  immap = (immap_t *) (mfspr (IMMR) & 0xffff0000);  immap->im_memctl.memc_br7 = BR7_SET;  immap->im_memctl.memc_or7 = OR7_SET;#ifdef DEBUG  printk ("br7 = 0x%08x\n", immap->im_memctl.memc_br7);  printk ("or7 = 0x%08x\n", immap->im_memctl.memc_or7);#endif  /*memory map */  virt_base = (unsigned long) ioremap (LCD_BASE, LCD_VIRT_LENGTH);  return SUCCESS;}static voidlcd_ctr_init (void){  mdelay (15);  lcd_set (FUNCTION_SET);  mdelay (4);  lcd_set (DISPLAY_OFF);  lcd_set (DISPLAY_ON);  lcd_set (INPUT_MODE_SET);  lcd_set (DISPLAY_CLEAR);#ifdef DEBUG  showch (0x48);#endif}static voidlcd_set (unsigned char command){  writeb (command, (LCD_DATA_ADDR-LCD_BASE)+virt_base); /*first output control command */  udelay (10);  writeb (WRITE_REG | ENABLE_OFF, (LCD_CTRREG_ADDR - LCD_BASE) + virt_base);  udelay (1);  writeb (WRITE_REG | ENABLE_ON, (LCD_CTRREG_ADDR - LCD_BASE) + virt_base);  udelay (1);  writeb (WRITE_REG | ENABLE_OFF, (LCD_CTRREG_ADDR - LCD_BASE) + virt_base);  mdelay (40);			/*wait for command to ouput to lcd register */#ifdef DEBUG  printk ("Lcd port output data finished\n");#endif}static voidshowch (unsigned char ch){  writeb (BIT_SWAP (ch), (LCD_DATA_ADDR - LCD_BASE) + virt_base);	/*first output data to port */  udelay (10);  writeb (WRITE_DATA | ENABLE_OFF, (LCD_CTRREG_ADDR - LCD_BASE) + virt_base);  udelay (1);  writeb (WRITE_DATA | ENABLE_ON, (LCD_CTRREG_ADDR - LCD_BASE) + virt_base);  udelay (1);  writeb (WRITE_DATA | ENABLE_OFF, (LCD_CTRREG_ADDR - LCD_BASE) + virt_base);  mdelay (40);			/*wait for date to ouput to lcd ram */}/*******************************************************Standard  driver operation functions****************************************************************//**Called whenever a process attempt to open the lcd device*/static intdevice_open (struct inode *inode, struct file *lcd_device_file){  if (device_open_num)		/*ensure open lcd device exclusively */    {      return -EBUSY;		/*lcd device has been open by other process */    }  /*   *Make sure that this module isn't removed while   *the lcd is open by increasing the lcd usage count   */  if (check_region (LCD_BASE, LCD_VIRT_LENGTH))    {      printk ("%s memory already in use\n", DEVICE_NAME);      return -EBUSY;    }  request_region (LCD_BASE, LCD_VIRT_LENGTH, DEVICE_NAME);  device_open_num++;  MOD_INC_USE_COUNT;  lcd_set (DISPLAY_CLEAR);  lcd_set (INPUT_MODE_SET);#ifdef DEBUG  printk (DEVICE_NAME " open successed \n");#endif  return SUCCESS;}/**Called whenever a process closes the lcd device*/static intdevice_release (struct inode *inode, struct file *lcd_device_file){  /*   *Make sure that this module isn't removed while   *the lcd is open by increasing the lcd usage count   */  device_open_num--;  MOD_DEC_USE_COUNT;  release_region (LCD_BASE, LCD_VIRT_LENGTH);#ifdef DEBUG  printk (DEVICE_NAME " closed successed \n");#endif  return SUCCESS;}/**The Lcd device driver write function*/static ssize_tdevice_write (struct file *lcd_device_file, const char *buffer,	/*buffer for data outputed to lcd */	      size_t length,	/*length of buffer */	      loff_t * offset)	/*file pointer offset */{  unsigned char ch;  int error;  int i = 0;  int line_count = 0;  while (i < length)    {      if (line_count < 16)	{	  if (line_count == 8)	    lcd_set (CHANGE_LINE);	  if ((error = get_user (ch, buffer)) != 0)	    {	      return 0;	    }	  buffer++;	  i++;	  line_count++;	  showch (ch);	}      else	{	  mdelay (2000);	  line_count = 0;	  lcd_set (DISPLAY_CLEAR);	}    }  return length;}/*************************************** Linux Module functions*********************************************/#ifdef MODULE/**Initialize the lcd device driver module*/intinit_module (void){  return lcd_init ();}/**Cleanup the lcd device driver moudle*/voidcleanup_module (){  int ret;#ifdef DEBUG  printk ("I realse myself from kernel\n");#endif  /*unmap memory */  iounmap ((void *) virt_base);  /* Unregister the device */  ret = unregister_chrdev (Major, DEVICE_NAME);  if (ret < 0)    {      printk ("unregister char_dev :error%d\n", ret);    }  lcd_set (DISPLAY_OFF);  lcd_set (DISPLAY_CLEAR);  writeb (LED_ON, (LED_ADDR - LCD_BASE) + virt_base);	/*turn on led */}#endif /*MODULE*/

⌨️ 快捷键说明

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