adc驅動(僅一路輸入)
/********s3c2410-adc.h********/
#ifndef _s3c2410_adc_h_
#define _s3c2410_adc_h_
#define adc_write(ch, prescale) ((ch)<<16|(prescale)) //將頻道和預分頻合併為乙個資料,這樣可以作為乙個引數傳入
#define adc_write_getch(data) (((data)>>16)&0x7) //得到轉換器是哪一路的,使用時要<<3
#define adc_write_getpre(data) ((data)&0xff) //得到預分頻的值
#endif /* _s3c2410_adc_h_ */
/*************************s3c2410-adc.c****************************/
#include
#include
#include
#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
#include
#include "s3c2410-adc.h"
#include
#define device_name "adc"
#define adcraw_minor 0
#define adc_input(x) ((x)<<3)
#define prscvl(x) ((x)<<6)
static void *adctsc;
static void *adccon;
static void *adcdata0;
static void *clkcon;
static int adc_major = 252;
typedef struct adc_dev;
static adc_dev adcdev;
/**中斷處理函式
*/static irqreturn_t adcdone_int_handler(int irq,void *dev_id,struct pt_regs *regs)
/**對裝置進行寫操作,buffer一定是使用者空間的
*/static ssize_t s3c2410_adc_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
copy_from_user(&data, buffer, count); //從使用者空間拷貝資料到核心空間
adcdev.channel=adc_write_getch(data); //得到哪一路ad轉換器
adcdev.prescale=adc_write_getpre(data); //得到預分頻值
//printk(kern_info"set adc channel=%d, prescale=0x%x\n", adcdev.channel, adcdev.prescale);
return count;}/*
*對裝置進行讀操作,buffer一定是使用者空間的
*/static ssize_t s3c2410_adc_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
/**開啟裝置
*/static int s3c2410_adc_open(struct inode *inode, struct file *filp)
init_mutex(&adcdev.lock); //初始化乙個互斥的訊號量,並設定為1
init_waitqueue_head(&(adcdev.wait));//初始化等待佇列
adcdev.channel=0;
adcdev.prescale=0xff;
printk(kern_info"adc opened\n");
return 0;}/*
*關閉裝置
*/static int s3c2410_adc_release(struct inode *inode, struct file *filp)
/**初始化並新增結構提struct cdev到系統之中
*/static void adc_setup_cdev( struct cdev *dev, int minor,
struct file_operations *fops)
static struct cdev adcdevs;
/**定義乙個file_operations結構體,來實現對裝置的具體操作的功能
*/static struct file_operations adc_remap_ops = ;
/**初始化裝置驅動模組,主要完成對字元裝置結構體的初始化和新增到系統中,並得到乙個裝置的裝置號
*/static int adc_init(void)
if (result < 0)
if (adc_major == 0)
adc_major = result;//如果靜態分配失敗。把動態非配的裝置號給裝置驅動程式
adc_setup_cdev(&adcdevs, 0, &adc_remap_ops);//初始化和新增結構體struct cdev到系統之中
printk(kern_info"adc device installed, with major %d\n", adc_major);
return 0;}/*
*解除安裝驅動模組
*/static void adc_cleanup(void)
module_init(adc_init);//初始化裝置驅動程式的入口
module_exit(adc_cleanup);//解除安裝裝置驅動程式的入口
module_license("dual bsd/gpl"); //模組應該指定**所使用的許可證
/******************main-adc.c*****************/
#include
#include
#include
#include
#include
#include
#include
#include "s3c2410-adc.h"
#define adc_dev "/dev/adc"
static int adc_fd = -1;
static int init_addevice(void)
}static int getadresult(int channel)
int main(void)
close(adc_fd);//關閉裝置
return 0;
}//備註:此驅動程式使用了等待佇列,訊號量,中斷註冊。另外要特別留意write函式被實現為從使用者空間傳入數模轉換通道號(頻道)和分頻的值(預分頻),read函式則傳出轉換好的資料。對於預分頻傳入和讀取,本驅動程式並未使用到,當多路轉換時,這個值則要充分利用,並且需要一種多路轉換的實現方法了。
全志 ADC驅動
adc 驅動 1 include 2 include 3 include 4 include 5 include 6 include 7 include 8 include 9 include 10 include 11 include 12 include 13 include 14 includ...
Linux驅動修煉之道 ADC驅動
對於s3c2440 來說,實現a d 轉換比較簡單,主要應用的是adc 控制暫存器adccon 和adc 轉換資料暫存器adcdat0 暫存器adcdat0 的低10 位用於儲存a d 轉換後的資料。暫存器adccon 的第15 位用於標識a d 轉換是否結束。第14 位用於使能是否進行預分頻,而第...
Linux驅動修煉之道 ADC驅動
對於s3c2440 來說,實現a d 轉換比較簡單,主要應用的是adc 控制暫存器adccon 和adc 轉換資料暫存器adcdat0 暫存器adcdat0 的低10 位用於儲存a d 轉換後的資料。暫存器adccon 的第15 位用於標識a d 轉換是否結束。第14 位用於使能是否進行預分頻,而第...