大家帮忙看一下,我的A/D驱动,使用中断方式,读出的数据没有变化,为什么?
#include
#include
#include
#include
#include
#include /* printk() */
#include /* kmalloc() */
#include /* everything... */
#include /* error codes */
#include /* size_t */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "s3c2410-adc.h"
#include
#include
#define DEVICE_NAME "adc"
static int adc_major = 252;
typedef struct {
struct semaphore lock;
wait_queue_head_t wait;
int channel;
int prescale;
}ADC_DEV;
static ADC_DEV adcdev;
int IRQ_flag=64;
static unsigned long *adccon, *adctsc, *adcdly, *adcdat0, *adcdat1, *adcupdn;
static irqreturn_t adcdone_int_handler(int irq,void *dev_id,struct pt_regs *regs) //*********irq_handle()********//
{
wake_up(&adcdev.wait);
printk("wake_up adcdev.wait ...\n");
return IRQ_HANDLED;
}
static int s3c2410_adc_open(struct inode *inode, struct file *filp) //********open()***********//
{
init_MUTEX(&adcdev.lock);
init_waitqueue_head(&(adcdev.wait));
adcdev.channel=0;
adcdev.prescale=19; //#define IRQ_FREQ 2500000 prescale=50000000/IRQ_FREQ-1;
printk("open OK\n");
//try_module_get(THIS_MODULE);
return 0;
}
static ssize_t s3c2410_adc_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)//*****write()*****//
{
return 0;
}
static ssize_t s3c2410_adc_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)//*********read()**********//
{
int ret = 0;
int i=0;
unsigned long temp0,temp1;
if (down_interruptible(&adcdev.lock))
return -ERESTARTSYS;
writel((readl(S3C2410_CLKCON) | S3C2410_CLKCON_ADC),S3C2410_CLKCON); //
writel((0x01 < <14) | PRSCVL(adcdev.prescale) | (adcdev.channel < <3) | 0x1 | 0x1 , adccon);
//
printk("reading...adccon=%d\n",readl(adccon));
//interruptible_sleep_on(&adcdev.wait); //
temp0=readl(adccon)&0x1;
printk("so...temp0=%d\n",temp0);
for(i=0;i <20000;i++);
//while(!(temp0& 0x1));
temp1=readl(adccon);
temp1=temp1 & 0x8000;
printk("so...temp1111=%ld\n",temp1);
while((temp1 & 0x8000)!=1)udelay(1);
printk("now...adccon=%d\n",readl(adccon));
ret = readl(adcdat0);
ret &= 0x3ff;
printk("reading...ret=%d adcdat0=%d\n",ret,readl(adcdat0));
copy_to_user(buffer, (char *)&ret, sizeof(ret));
up(&adcdev.lock);
return sizeof(ret);
}
static int s3c2410_adc_release(struct inode *inode, struct file *filp) //*********release()**********//
{
free_irq(IRQ_flag, NULL);
//module_put(THIS_MODULE);
printk( "adc closed\n");
return 0;
}
static void adc_setup_cdev(struct cdev *dev, int minor,
struct file_operations *fops)
{
int err, devno = MKDEV(adc_major, minor);
cdev_init(dev, fops);
dev->owner = THIS_MODULE;
dev->ops = fops;
err = cdev_add (dev, devno, 1);
/* Fail gracefully if need be */
if (err)
printk (KERN_NOTICE "Error %d adding adc %d", err, minor);
}
static struct cdev AdcDevs; //char?豸????
static struct file_operations adc_remap_ops = {
.owner =THIS_MODULE,
.open = s3c2410_adc_open,
.read = s3c2410_adc_read,
.write = s3c2410_adc_write,
.release = s3c2410_adc_release,
};
int __init adc_init(void)
{
int result;
int ret;
dev_t dev;
printk("initing...\n");
/* normal ADC */
//writel(0,S3C2410_ADCTSC); //XP_PST(NOP_MODE);
dev = MKDEV(adc_major, 0);
/* Figure out our device number. */
if (adc_major)
result = register_chrdev_region(dev, 1, "adc");
else {
result = alloc_chrdev_region(&dev, 0, 1, "adc");
adc_major = MAJOR(dev);
}
if (result < 0) {
printk(KERN_WARNING "adc: unable to get major %d\n", adc_major);
return result;
}
if (adc_major == 0)
adc_major = result;
ret = request_irq(IRQ_flag, &adcdone_int_handler, SA_INTERRUPT, DEVICE_NAME, NULL);
printk("ret=%d\n",ret);
if (ret) {
return ret;
}
adc_setup_cdev(&AdcDevs, 0, &adc_remap_ops);
adccon = ioremap(S3C2410_ADCCON,0x00000004);
adcdat0 = ioremap(S3C2410_ADCDAT0,0x00000004);
printk("adc device installed, with major %d IRQ_flag=%d\n", adc_major,IRQ_flag);
return 0;
}
static void adc_cleanup(void)
{
iounmap(adccon);
iounmap(adcdat0);
cdev_del(&AdcDevs);
unregister_chrdev_region(MKDEV(adc_major, 0), 1);
printk("adc device uninstalled\n");
}
module_init(adc_init);
module_exit(adc_cleanup);
MODULE_AUTHOR("Shuchen Xie");
MODULE_LICENSE("GPL");