#include <linux/module.h>
#include <linux/fs.h>
#include <asm/io.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <asm/uaccess.h>
#include <linux/errno.h>
#include <linux/types.h>
MODULE_LICENSE("GPL");
unsigned int lcd_major = 0;
static int open_lcd(struct inode *, struct file *);
static ssize_t read_lcd(struct file *, char *, size_t , loff_t *);
static int ioctl_lcd(struct inode *, struct file *, unsigned int cmd, unsigned long);
static ssize_t write_lcd(struct file *, const char *, size_t, loff_t *);
static int close_lcd(struct inode *, struct file *);
static void delay();
static int open_lcd(struct inode *inode, struct file *file)
{
return 0;
}
static ssize_t read_lcd(struct file *file, char *buf, size_t len, loff_t *off)
{
return 0;
}
static ssize_t write_lcd(struct file *file, const char *buf, size_t len, loff_t *off)
{
unsigned char *lcd_data_addr;
unsigned char data;
lcd_data_addr = ioremap((unsigned long)0x30000000, (unsigned long)1);
data = *buf;
writeb(data, lcd_data_addr);
iounmap((void *)lcd_data_addr);
return *off;
}
static int ioctl_lcd(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
unsigned char *lcd_row_addr;
unsigned char *lcd_list_addr;
unsigned char *lcd_control_addr;
unsigned char *lcd_data_addr;
unsigned char ctrl;
unsigned char row;
unsigned char list;
unsigned char data;
int i, j;
lcd_control_addr = ioremap((unsigned long)0x3000000c, (unsigned long)1);
lcd_row_addr = ioremap((unsigned long)0x30000004, (unsigned long)1);
lcd_list_addr = ioremap((unsigned long)0x30000008, (unsigned long)1);
lcd_data_addr = ioremap((unsigned long)0x30000000, (unsigned long)1);
switch(cmd)
{
case 1:
//printk("before ctrl=0x%x\n", ctrl);
copy_from_user(&ctrl, (unsigned char *)arg, sizeof(unsigned char));
//printk("ofter ctrl=0x%x\n", ctrl);
writeb(ctrl, lcd_control_addr);
delay();
break;
case 2:
copy_from_user(&row, (unsigned char *)arg, sizeof(unsigned char));
writeb(row, lcd_row_addr);
delay();
break;
case 3:
copy_from_user(&list, (unsigned char *)arg, sizeof(unsigned char));
writeb(list, lcd_list_addr);
delay();
break;
case 4:
copy_from_user(&data, (unsigned char *)arg, sizeof(unsigned char));
//printk("kernel data=0x%x\n", data);
for(i = 0; i < 234; i++)
{
writeb(row, lcd_row_addr);
delay();
writeb(list, lcd_list_addr);
delay();
writeb(list, lcd_list_addr);
delay();
for(j = 0; j < 320; j++)
{
writeb(data, lcd_data_addr);
delay();
}
row = row + 0x01;
}
}
iounmap((void *)lcd_control_addr);
iounmap((void *)lcd_row_addr);
iounmap((void *)lcd_list_addr);
iounmap((void *)lcd_data_addr);
return - ENOTTY;
}
static int close_lcd(struct inode *inode, struct file *file)
{
return 0;
}
struct file_operations lcd_fops =
{
open:open_lcd,
read:read_lcd,
write:write_lcd,
ioctl:ioctl_lcd,
release:close_lcd,
};
int init_module(void)
{
int ret;
ret = register_chrdev(lcd_major, "lcd", &lcd_fops);
if(ret < 0)
{
printk("lcd register error\n !!!");
return ret;
}
else
{
if(lcd_major == 0)
{
lcd_major = ret;
printk("lcd register success,lcd major is %d !!!\n", ret);
}
else
{
printk("lcd register success,lcd major is %d !!!\n", lcd_major);
}
}
return 0;
}
void cleanup_module(void)
{
int ret;
ret = unregister_chrdev(lcd_major, "lcd");
if (ret < 0)
{
printk("test_var unregister failure !!!\n");
}
else
{
printk("test_var unregister success!!!\n");
}
}
void delay()
{
int i,j;
for(i=0;i<=1;i++)
for(j=0;j<=100;j++)
{
;
}
}