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

📄 tlc3544.c~

📁 AD转换器TLC3544在Linux2.6内核中的驱动程序 本人已经调试过 可以成功运行
💻 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 + -