| 本帖最后由 月骅 于 2012-9-5 12:47 编辑 
 /*************************************
 
 NAME:EmbedSky_hello.c
 COPYRIGHT:www.embedsky.net
 
 *************************************/
 #include <linux/miscdevice.h>
 #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/clk.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <mach/regs-clock.h>
 #include <plat/regs-timer.h>
 #include <linux/fs.h>
 #include <plat/regs-adc.h>
 #include <mach/regs-gpio.h>
 #include <linux/cdev.h>
 #include "tq2440_adc.h"
 #include <linux/interrupt.h>
 #undef DEBUG
 #define DEBUG
 #ifdef DEBUG
 #define DPRINTK(x...) {printk(__FUNCTION__);printk("(%d): ",__LINE__);printk(x);}
 #else
 #define DPRINTK(x...) (void)(0)
 #endif
 #define DEVICE_NAME        "adc"
 static void __iomem *base_addr;
 struct adc_dev
 {
 struct cdev cdev;
 struct semaphore lock;
 int channel;
 int prescale;
 };
 
 struct adc_dev adc_dev;
 struct adc_dev *adc_devp;
 static struct clk        *adc_clock;
 #define START_ADC(ch, prescale) S3C2410_ADCCON_PRSCEN |S3C2410_ADCCON_PRSCVL(prescale) \
 | S3C2410_ADCCON_SELMUX(ch) | S3C2410_ADCCON_ENABLE_START
 
 static ssize_t adc_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
 {
 unsigned long result=0;
 unsigned int data;
 if (down_interruptible(&adc_dev.lock))
 return -ERESTARTSYS;
 iowrite32(START_ADC(adc_dev.channel,adc_dev.prescale),base_addr + S3C2410_ADCCON);
 do{
 result=ioread32(base_addr+S3C2410_ADCCON);
 }while((unsigned int)result&0x01);//ensure the start of conversion
 do{
 result=ioread32(base_addr+S3C2410_ADCCON);
 }while(!(((unsigned int)result)&0x8000));//till the end of conversion
 data = ioread32(base_addr + S3C2410_ADCDAT0) & 0x3ff;
 copy_to_user(buffer,&data,sizeof(data));
 up(&adc_dev.lock);
 return sizeof(result);
 }
 
 static int adc_open(struct inode *inode, struct file *filp)
 {
 init_MUTEX(&adc_dev.lock);
 filp->private_data = adc_devp;
 adc_dev.channel=2;
 adc_dev.prescale=0x13;
 base_addr=ioremap(S3C2410_PA_ADC,0x20);
 adc_clock=clk_get(NULL,"adc");
 if (!adc_clock) {
 DPRINTK("failed to get adc clock source\n");
 return -ENOENT;
 }
 clk_enable(adc_clock);
 DPRINTK( "ADC opened\n");
 return 0;
 }
 
 static int adc_release(struct inode *inode, struct file *filp)
 {
 DPRINTK( "ADC closed\n");
 return 0;
 }
 
 
 static struct file_operations adc_fops = {
 owner:        THIS_MODULE,
 open:        adc_open,
 read:        adc_read,
 release:        adc_release,
 };
 
 static struct miscdevice misc = {
 .minor = MISC_DYNAMIC_MINOR,
 .name = DEVICE_NAME,
 .fops = &adc_fops,
 };
 static int __init adc_init(void)
 {
 int ret;
 ret=misc_register(&misc);
 if(ret<0)
 return ret;
 adc_devp=kmalloc(sizeof(struct adc_dev),GFP_KERNEL);
 if(!adc_devp)
 ret=-ENOMEM;
 memset(adc_devp,0,sizeof(struct adc_dev));
 return 0;
 return ret;
 }
 
 static void __exit adc_exit(void)
 {
 iounmap(base_addr);
 
 if (adc_clock)
 {
 clk_disable(adc_clock);
 clk_put(adc_clock);
 adc_clock = NULL;
 }
 kfree(adc_devp);
 misc_deregister(&misc);
 }
 module_init(adc_init);
 module_exit(adc_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("jetsu.zju@gmail.com");
 MODULE_DESCRIPTION("adc driver for my 10000 points");
 ————————————————————————————————————————————————————————————
 改成了查询方式的ADC,还是不能达到1K points每秒啊,肿么办,求破。
 
 
 |