📄 tlc3544.c~
字号:
/* * FileName zlg7289a.h * Author wangzhenhui * Date 09/21/06 * Board SESI_AT91RM9200EDUKIT * Desc on board keyboard and LED driver */#include <linux/config.h>#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/init.h>#include <linux/kernel.h> /* printk() */#include <linux/slab.h> /* kmalloc() */#include <linux/fs.h> /* everything... */#include <linux/errno.h> /* error codes */#include <linux/types.h> /* size_t */#include <linux/proc_fs.h>#include <linux/fcntl.h> /* O_ACCMODE */#include <linux/seq_file.h>#include <linux/cdev.h>#include <linux/delay.h>#include <asm/system.h> /* cli(), *_flags */#include <asm/uaccess.h> /* copy_*_user */#include <asm/arch/board.h>#include <asm/arch/gpio.h>#include <asm/hardware.h>#include <linux/interrupt.h>#include <asm/irq.h>#include "zlg7289.h"static int zlg7289_open(struct inode *, struct file *);static int zlg7289_close(struct inode *, struct file *);static int zlg7289_read(struct file *, char *, size_t, loff_t *);static int zlg7289_write(struct file *, const char *, size_t, loff_t *);static irqreturn_t zlg7289_interrupt (int , void *, struct pt_regs *);static void zlg7289_hardware_init(void);static unsigned char zlg7289_transform(unsigned char, unsigned char, int);static void uled_control(int, unsigned char);int zlg7289_major = 0;int zlg7289_minor = 0;struct zlg7289_dev *zlg7289_device;static struct file_operations zlg7289_fops = { open: zlg7289_open, read: zlg7289_read, write: zlg7289_write, release: zlg7289_close,};static int input_flag = 0;static unsigned char input_data = 0xff;static void zlg7289_hardware_init (void){ DBG_ZLG7289("zlg7289_hardware_init\n"); at91_set_gpio_output(ZLG_CS,0); at91_set_gpio_output(ZLG_DATA,0); at91_set_gpio_output(ZLG_CLK,0); at91_set_gpio_output(USER_LED1,0); at91_set_gpio_output(USER_LED2,0); at91_set_gpio_output(USER_LED3,0); at91_set_gpio_output(USER_LED4,0); at91_set_gpio_input(ZLG_KEY,0); at91_set_gpio_value(USER_LED1,1); at91_set_gpio_value(USER_LED2,1); at91_set_gpio_value(USER_LED3,1); at91_set_gpio_value(USER_LED4,1); at91_set_gpio_value(ZLG_CS,1); }static void uled_control (int index, unsigned char on_off){ DBG_ZLG7289("uled_control index=%d, on_off=%d\n", index, on_off); switch (index){ case 1: at91_set_gpio_value(USER_LED1,on_off); break; case 2: at91_set_gpio_value(USER_LED2,on_off); break; case 3: at91_set_gpio_value(USER_LED3,on_off); break; case 4: at91_set_gpio_value(USER_LED4,on_off); break; default: return; } return;}static unsigned char zlg7289_transform (unsigned char cmd, unsigned char data, int type){ int i; unsigned char bit, read_data=0; DBG_ZLG7289("zlg7289_transform cmd=%x, data=%x, type=%x\n", cmd, data, type); /* CS# Low */ at91_set_gpio_value(ZLG_CS,0); udelay(50); /* Transform CMD */ for(i=1; i<=8; i++){ /* CMD Output */ bit = ( cmd >> (8-i) ) & 0x01 ; //DBG_ZLG7289("zlg7289_transform bit %x\n", bit); at91_set_gpio_value(ZLG_DATA,bit); udelay(50); /* CLK High */ at91_set_gpio_value(ZLG_CLK,1); udelay(50); /* CLK Low */ at91_set_gpio_value(ZLG_CLK,0); udelay(50); } switch (type) { case TRAN_CMD: break; case TRAN_CMD_DATA: /* Transform DATA */ for(i=7; i>=0; i--){ /* DATA Output */ bit = ( data >> i ) & 0x01 ; at91_set_gpio_value(ZLG_DATA,bit); udelay(50); /* CLK High */ at91_set_gpio_value(ZLG_CLK,1); udelay(50); /* CLK Low */ at91_set_gpio_value(ZLG_CLK,0); udelay(50); } break; case READ_CMD_DATA: /* DATA Input */ at91_set_gpio_input(ZLG_DATA,0); /* Read DATA */ for(i=7; i>=0; i--){ /* CLK High */ at91_set_gpio_value(ZLG_CLK,1); udelay(25); if( at91_get_gpio_value(ZLG_DATA)!= 0 ) read_data |= 1 << i; udelay(25); /* CLK Low */ at91_set_gpio_value(ZLG_CLK,0); udelay(50); } /* DATA Output */ at91_set_gpio_output(ZLG_DATA,0); break; default: DBG_ZLG7289("zlg7289_transform error type %x\n", type); break; }//end switch /* CS# High */ at91_set_gpio_value(ZLG_CS,1); udelay(50); DBG_ZLG7289("zlg7289_transform: read_data = %x\n", read_data); return read_data;}static int zlg7289_open (struct inode *inode, struct file *file){ DBG_ZLG7289("zlg7289_open\n"); zlg7289_device->use_count++; if(zlg7289_device->use_count==1)file->private_data = zlg7289_device; return 0;}static int zlg7289_close (struct inode *inode, struct file *file){ DBG_ZLG7289("zlg7289_close\n"); zlg7289_device->use_count--; return 0;}static int zlg7289_read (struct file *file, char *buf, size_t count, loff_t *ppos){ DBG_ZLG7289("zlg7289_read: input_flag %d\n", input_flag); put_user(input_data, buf);// input_flag = 0; input_data = 0xff; return count;}static int zlg7289_write (struct file *file, const char *buf, size_t count, loff_t *ppos){ unsigned char cmd_type, on_off, cmd, data; DBG_ZLG7289("zlg7289_write: %p\n", buf); get_user(cmd_type, buf++); switch (cmd_type) { case ULED1_CONTROL: get_user(on_off, buf); uled_control(1, on_off); break; case ULED2_CONTROL: get_user(on_off, buf); uled_control(2, on_off); break; case ULED3_CONTROL: get_user(on_off, buf); uled_control(3, on_off); break; case ULED4_CONTROL: get_user(on_off, buf); uled_control(4, on_off); break; case ZLG_CMD: get_user(cmd, buf); zlg7289_transform(cmd, 0, TRAN_CMD); break; case ZLG_CMD_DATA: get_user(cmd, buf++); get_user(data, buf); zlg7289_transform(cmd, data, TRAN_CMD_DATA); break; default: DBG_ZLG7289("zlg7289_write: cmd_type = %d error\n", cmd_type); break; }//end switch return count; }static irqreturn_t zlg7289_interrupt (int irq, void *dev_id, struct pt_regs *regs){ unsigned char data = 0; //DBG_ZLG7289("zlg7289_interrupt\n"); data = zlg7289_transform(0x15, 0, READ_CMD_DATA); printk("zlg7289_interrupt: key = %x\n", data); if( data != 0xff){ input_flag = 1; input_data = data; } return 0;}void zlg7289_cleanup_module(void){ dev_t devno = MKDEV(zlg7289_major, zlg7289_minor); printk("zlg7289 module cleanup.\n"); cdev_del(&zlg7289_device->cdev); kfree(zlg7289_device); unregister_chrdev_region(devno, 1); }int zlg7289_init_module(void){ int result,dev_no; dev_t dev = 0; zlg7289_hardware_init (); /* ask for a dynamic major */ result = alloc_chrdev_region(&dev, zlg7289_minor, 0, "zlg7289"); zlg7289_major = MAJOR(dev); if (result < 0) { printk(KERN_WARNING "zlg7289: can't get major %d\n", zlg7289_major); return result; } /* mem alloc for device */ zlg7289_device = kmalloc(sizeof(struct zlg7289_dev), GFP_KERNEL); if (!zlg7289_device) { result = -ENOMEM; printk(KERN_WARNING "ads 7843 memory alloc failed.\n"); goto fail; /* Make this more graceful */ } memset(zlg7289_device, 0, sizeof(struct zlg7289_dev)); /* init mutex */ init_MUTEX(&(zlg7289_device->sem)); /* reg device */ dev_no = MKDEV(zlg7289_major, zlg7289_minor); cdev_init(&zlg7289_device->cdev, &zlg7289_fops); zlg7289_device->cdev.owner = THIS_MODULE; zlg7289_device->cdev.ops = &zlg7289_fops; result = cdev_add (&zlg7289_device->cdev, dev_no, 1); /* Fail gracefully if need be */ if (result){ printk(KERN_NOTICE "Error %d adding zlg7289.\n", result); goto fail; } result=request_irq(AT91_ID_IRQ0, zlg7289_interrupt, SA_SAMPLE_RANDOM | SA_TRIGGER_FALLING, "zlg7289", zlg7289_device); if(result) { printk(KERN_NOTICE "Error %d adding zlg7289.\n", result); goto fail; } //zlg7289_startup(zlg7289_device); printk("zlg7289 module init major:%d.\n",zlg7289_major); return 0;fail: zlg7289_cleanup_module(); return result;}module_init(zlg7289_init_module);module_exit(zlg7289_cleanup_module);MODULE_AUTHOR("Zhenhui wang, wangzhenhui2002@hotmail.com");MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -