ARM Linux S3C2440之ADC驱动实现
- UID
- 1029342
- 性别
- 男
|
ARM Linux S3C2440之ADC驱动实现
硬件描述: S3c2440有一个10-bit的CMOS ADC 模数转换器,支持8个模拟通道输入,10位的分辨率,最高速度可达500KSPS(500 千次/每秒)。
从图中可知:模拟ADC,包含了2部分功能,一部分是触屏功能,另一部分就是普通ADC功能,分别可以产生INT_TC和INT_ADC 两个中断。8个AIN模拟输入(A[3:0],YM,YP,XM,XP)通过一个8路模拟开关MUX进行通道片选。 ADC模块共有20个寄存器。对于普通ADC转换,使用ADCCON 和 ADCDAT0即可完成控制。ADCCON用于控制设置,ADCDAT0保存了转换结果。
驱动程序ADC_DEV.ko:
[cpp]
- #include <linux/errno.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/clk.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <linux/interrupt.h>
#include <mach/regs-clock.h>
#include <plat/regs-adc.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#define DEVICE_NAME "ADC_DEV"
struct ADC_DEV { - wait_queue_head_t wait;
int ch;
int pres;
int data;
int flag; - };
static
struct ADC_DEV adc_dev;
static
void __iomem *ADC_REG_BASE;
static
struct clk *adc_clk;
#define ADCCON (*(volatile unsigned long *)(ADC_REG_BASE + S3C2410_ADCCON))
#define ADCDAT0 (*(volatile unsigned long *)(ADC_REG_BASE + S3C2410_ADCDAT0))
#define START_ADC(ch,pres) ADCCON = (0x01 | 0x01<<14 | ch<<3 | pres<<6)
static ssize_t adc_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos) - {
- START_ADC(adc_dev.ch, adc_dev.pres); //启动ADC转换
- wait_event_interruptible(adc_dev.wait,adc_dev.flag); //等待ADC转换完成
- adc_dev.flag = 0;
- copy_to_user(buf,(char*)&adc_dev.data,sizeof(adc_dev.data));
return (sizeof(adc_dev.data)); - }
static
int adc_open(struct inode *in, struct file *fp) - {
- adc_dev.ch = 0x02; //输入通道2
- adc_dev.pres = 0xff; //prescale : 0 ~255 可选
- adc_dev.data = 0;
- adc_dev.flag = 0;
- init_waitqueue_head(&(adc_dev.wait));
return 0; - }
|
|
|
|
|
|