#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/serio.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <mach/regs-clock.h>
#include <plat/regs-timer.h>
#include <plat/regs-adc.h>
#include <mach/regs-gpio.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>
#define ADC_MAJOR 201 // 主设备号
#define DEVICE_NAME "adc_dev" // 设备名
#define SUCCESS 0
#define adc_con (unsigned long)ioremap(0x58000000,4) //
#define adc_dat0 (volatile unsigned long)ioremap(0x5800000c,4)
static int Device_Open = 0;
int adc_init(void);
//void devfs_mk_cdev(int,int,char*);
void adc_cleanup(void);
static int device_open(struct inode *,struct file *);
static int device_release(struct inode *,struct file *);
static ssize_t device_read();
static ssize_t device_ioctl(struct inode *,struct file *,unsigned int,unsigned long);
int init_module(void);
void cleanup_module(void);
struct file_operations adc_ops = // < linux/fs.h >
{
.owner = THIS_MODULE,
.read = device_read,
.ioctl = device_ioctl,
.open = device_open,
.release = device_release,
};
static int Major;
int __init adc_init(void) // 初始化
{
Major = register_chrdev(ADC_MAJOR,DEVICE_NAME,&adc_ops); // 设备注册
if(Major <0)
{
printk("ADC init_module:failed with %d\n",Major);
return Major;
}
//devfs_mk_cdev(MKDEV(ADC_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR |
//S_IRGRP,DEVICE_NAME);
printk(DEVICE_NAME " initialized\n");
return 0;
}
static int device_open(struct inode * inode,struct file *file)
{
if(Device_Open)
{
return -EBUSY;
}
Device_Open++; //
return SUCCESS;
}
static int device_release(struct inode * inode,struct file *file)
{
Device_Open --;
return 0;
}
static int adc_setadccon(void)
{
__raw_writel((1<<14)|(0x5<<6), adc_con); // 设置 ADCCON
return 0;
}
static ssize_t device_read(void)
{
unsigned long buf;
__raw_writel(__raw_readl(adc_con)|0x1, adc_con); // 启动AD转换
while(__raw_readl(adc_con) &0x1); // 启动转换后等待启动位清零
while(!(__raw_readl(adc_con) & 0x8000)); // 等待转换是否完毕
buf=__raw_readl(adc_dat0) & 0x3ff; // 读取数据
//*buffer=(unsigned char)buf;
//buffer++;
//*buffer=(unsigned char)(buf>>8);
return buf;
}
static ssize_t device_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg)
{
unsigned long val;
switch(cmd){
case(0):
adc_setadccon();
return 0;
case(1):
val=device_read();
return val;
}
}
void adc_cleanup() // 卸载
{
//int ret;
unregister_chrdev(Major,DEVICE_NAME);
//if(ret < 0)
//{
// printk("unregister_chrdev:error %d\n",ret);
//}
}
module_init(adc_init);
module_exit(adc_cleanup);
MODULE_LICENSE("GPL");
[ 此帖被qinqin04在2009-04-22 21:15重新编辑 ]