mini2440adc驱动

#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/init.h>
#include <linux/serio.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/gpio.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <mach/regs-clock.h>
#include <plat/regs-timer.h>
#include <plat/regs-adc.h>
#include <mach/regs-gpio.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/poll.h>
static DECLARE_WAIT_QUEUE_HEAD(adc_wait); 
static int major=0;
static int adc_flage=0;
static struct clk *adc_clock;
struct cdev adc_devices;
static struct class *adc_class;
static struct class_device	*adc_class_dev;
static volatile unsigned long *adccon;
static volatile unsigned long *adctsc;
static volatile unsigned long *adcdly;
static volatile unsigned long *adcdat0;
static volatile unsigned long *adcdat1;
static volatile unsigned long *adcupdn;
static void adc_start()
{
	*adccon |=0x01;
	
}
		
static irqreturn_t s3c2410_adc_irq(int irq, void *dev_id)
{  
	
	adc_flage=1;
	wake_up_interruptible(&adc_wait);
	return IRQ_RETVAL(IRQ_HANDLED);
}
	
static int s3c2410_adc_open(struct inode *inode, struct file *file)
{	
	int re;
	adccon  = ioremap(0x58000000,4); /*映射adc寄存器*/
	adcdat0 = ioremap(0x5800000c,4);
	re=request_irq(IRQ_ADC,s3c2410_adc_irq,IRQF_SHARED,"2410adc",1);
	if(re<0)
		{
			printk("%s %s %d\n",__FILE__,__FUNCTION__,__LINE__);
		}	
	return 0;
}
static ssize_t adc_drv_read  (struct file *file, char __user *buf, size_t size, loff_t * opps)
{
	int data0;
	int data1;
	wait_event_interruptible(adc_wait,adc_flage); 
	data1=*adcdat0;
	data0=data1&0x3ff;/*读出转换数据*/
	copy_to_user(buf,&data0,sizeof(data0));/*拷贝到用户空间*/
 	adc_flage=0;
	adc_start();
	return  size;
 }
static 	ssize_t s3c2410_adc_write (struct file *file, const char __user *buf, size_t size, loff_t *opps)
{
	char val;
	static char chanel;
	copy_from_user(&val, buf, 1);
        chanel=val;
	switch(chanel)
	{
		case 0: 
				*adccon = ((0x01 << 14)|(0xff<<6)|(0x00<< 3)) ; /*分频使能*/
				break;

		case 1: 
				*adccon = ((0x01 << 14)|(0xff<<6)|(0x01<< 3)) ; /*分频使能*/
				break;
	
		case 2: 
				*adccon = ((0x01 << 14)|(0xff<<6)|(0x02<< 3)) ; /*分频使能*/
				break;

		case 3:
				*adccon = ((0x01 << 14)|(0xff<<6)|(0x03<< 3)) ; /*分频使能*/
				break;
		
	}
   	adc_start();
	return 0;
}
static loff_t s3c2410_adc_llseek (struct file *file, loff_t offset, int orig)
{
	loff_t ret=0;
	file->f_pos=(unsigned int )offset;
	ret=file->f_pos;
	return ret;


}
static void s3c2410_adc_close(struct inode *inode, struct file *file)
{
	   return 0;
}
static struct file_operations s3c2410_adc_ops = {	
	.owner   =  THIS_MODULE,  
	.open    = s3c2410_adc_open,
	.write   = s3c2410_adc_write,
	.read	 = adc_drv_read,
	.release = s3c2410_adc_close,	
};

static dev_t s3c2410_dev;

static int s3c2410_adc_init(void)
{	

	int ret;
	int error;
	int re;
	adc_clock = clk_get(NULL, "adc");
	clk_enable(adc_clock);
	s3c2410_dev = MKDEV(major, 0);		
	if (major)
		ret = register_chrdev_region(s3c2410_dev, 1, "adc_devices");	
	else {		
			ret = alloc_chrdev_region(&s3c2410_dev, 0, 1, "adc_devices");	
			major = MAJOR( s3c2410_dev);
		}	
	if (ret < 0)
		{	
			printk(KERN_WARNING "adc_devices: File exists: unable to get major %d\n", major);	
			return ret;	
		}
	cdev_init(&adc_devices, &s3c2410_adc_ops);
	
	if ((ret = cdev_add(&adc_devices,s3c2410_dev, 1)) != 0) {
		printk(KERN_ERR "dvb-core: unable register character device\n");
		goto error;
	}

	adc_class=class_create(THIS_MODULE, "adc_devices");  /*创建类*/
	if (IS_ERR(adc_class)) {
		ret = PTR_ERR(adc_class);
		goto error;
	}
	adc_class_dev= device_create(adc_class, NULL, MKDEV(major, 0), NULL, "2410adc");
	if (!adc_class_dev) {
			printk(KERN_ERR "device_create failed for adc_drv\n");
		
			goto error;
	}

	
	return 0;
	error:
	cdev_del(&adc_devices);
	unregister_chrdev_region(s3c2410_dev, 1);
	return ret;
	
	
}
static void s3c2410_adc_exit(void)
{
	
	iounmap(adccon);
	iounmap(adcdat0);
	clk_disable(adc_clock);
	clk_put(adc_clock);
	free_irq(IRQ_ADC, NULL);
	cdev_del(&adc_devices);
	unregister_chrdev_region(s3c2410_dev, 1);
	device_destroy( adc_class_dev, s3c2410_dev);	
	class_destroy(adc_class);

	return 0;

}	
module_init(s3c2410_adc_init);
module_exit(s3c2410_adc_exit);
MODULE_AUTHOR("4M小水管");
MODULE_LICENSE("GPL");


 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值