设为首页 加入收藏

TOP

mini6410 adc驱动程序(一)
2014-11-24 12:49:22 来源: 作者: 【 】 浏览:0
Tags:mini6410 adc 驱动程序

mini6410 adc驱动程序:


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#include
#include
#include
#include


#include "s3c24xx-adc.h"


#undef DEBUG
//#define DEBUG
#ifdef DEBUG
#define DPRINTK(x...) {printk(__FUNCTION__"(%d): ",__LINE__);printk(##x);}
#else
#define DPRINTK(x...) (void)(0)
#endif


#define DEVICE_NAME "adc"


static void __iomem *base_addr;


typedef struct {
wait_queue_head_t wait;
int channel;
int prescale;
}ADC_DEV;


DECLARE_MUTEX(ADC_LOCK);
static int OwnADC = 0;


static ADC_DEV adcdev;
static volatile int ev_adc = 0;
static int adc_data;


static struct clk *adc_clock;


#define ADCCON (*(volatile unsigned long *)(base_addr + S3C2410_ADCCON)) //ADC control
#define ADCTSC (*(volatile unsigned long *)(base_addr + S3C2410_ADCTSC)) //ADC touch screen control
#define ADCDLY (*(volatile unsigned long *)(base_addr + S3C2410_ADCDLY)) //ADC start or Interval Delay
#define ADCDAT0 (*(volatile unsigned long *)(base_addr + S3C2410_ADCDAT0)) //ADC conversion data 0
#define ADCDAT1 (*(volatile unsigned long *)(base_addr + S3C2410_ADCDAT1)) //ADC conversion data 1
#define ADCUPDN (*(volatile unsigned long *)(base_addr + 0x14)) //Stylus Up/Down interrupt status


#define PRESCALE_DIS (0 << 14)
#define PRESCALE_EN (1 << 14)
#define PRSCVL(x) ((x) << 6)
#define ADC_INPUT(x) ((x) << 3)
#define ADC_START (1 << 0)
#define ADC_ENDCVT (1 << 15)


#define START_ADC_AIN(ch, prescale) \
do{ \
ADCCON = PRESCALE_EN | PRSCVL(prescale) | ADC_INPUT((ch)) ; \
ADCCON |= ADC_START; \
}while(0)



static irqreturn_t adcdone_int_handler(int irq, void *dev_id)
{
if (OwnADC) {
adc_data = ADCDAT0 & 0x3ff;


ev_adc = 1;
wake_up_interruptible(&adcdev.wait);
}


return IRQ_HANDLED;
}


static ssize_t s3c2410_adc_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
{
char str[20];
int value;
size_t len;
if (down_trylock(&ADC_LOCK) == 0) {
OwnADC = 1;
START_ADC_AIN(adcdev.channel, adcdev.prescale);
wait_event_interruptible(adcdev.wait, ev_adc);


ev_adc = 0;


DPRINTK("AIN[%d] = 0x%04x, %d\n", adcdev.channel, adc_data, ADCCON & 0x80 1:0);


value = adc_data;
sprintf(str,"%5d", adc_data);
copy_to_user(buffer, (char *)&adc_data, sizeof(adc_data));


OwnADC = 0;
up(&ADC_LOCK);
} else {
value = -1;
}


len = sprintf(str, "%d\n", value);
if (count >= len) {
int r = copy_to_user(buffer, str, len);
return r r : len;
} else {
return -EINVAL;
}
}


static int s3c2410_adc_open(struct inode *inode, struct file *filp)
{
init_waitqueue_head(&(adcdev.wait));


adcdev.channel=0;
adcdev.prescale=0xff;


DPRINTK( "adc opened\n");
return 0;
}


static int s3c2410_adc_release(struct inode *inode, struct file *filp)
{
DPRINTK( "adc closed\n");
return 0;
}



static struct file_operations dev_fops = {
owner: THIS_MODULE,
open: s3c2410_adc_open,
read: s3c2410_adc_read,
release: s3c2410_adc_release,
};


static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &dev_fops,
};


static int __init dev_init(void)
{
int ret;


base_addr=ioremap(S3C2410_PA_ADC,0x20);
if (base_addr == NULL) {
printk(KERN_ERR "Failed to remap register block\n");
return -ENOMEM;
}


adc_clock = clk_get(NULL, "adc");
if (!adc_clock) {
printk(KERN_ERR "failed to get adc clock source\n");
return -ENOENT;
}
clk_enable(adc_clock);

/* normal ADC */
ADCTS

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Android中调用相册里面的图片并返.. 下一篇mini6410按键驱动程序

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·如何利用Python做数 (2025-12-24 23:48:36)
·如何使用python进行 (2025-12-24 23:48:34)
·python 爬虫入门该怎 (2025-12-24 23:48:31)
·Java 实现多个大文件 (2025-12-24 23:22:00)
·Java多线程编程在工 (2025-12-24 23:21:56)