#include <linux/wait.h>
#include <linux/sched.h>
#include <plat/regs-timer.h>
#include <plat/regs-adc.h>
#include <linux/device.h>
#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/platform_device.h>
#include <linux/clk.h>
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <linux/pci.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
#include <mach/map.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>
#include <plat/gpio-cfg.h>
#include <mach/gpio-bank-m.h>
#include <mach/gpio-bank-c.h>
#define ADC_MAJOR 0 /* ADC的主设备号 */
#define ADC_MINOR 0 /* ADC的次设备号 */
#define DEVICE_NAME "adc" /* 设备名 */
static int adc_major = ADC_MAJOR;
static int adc_minor = ADC_MINOR;
void *base;
#define S3C6410_ADC_BASE 0x7E00B000
#define ADCCON (*(volatile unsigned long *)(base + 0x0))
#define ADCDAT0 (*(volatile unsigned long *)(base + 0xc))
/* adcDevs设备结构体. */
struct cdev cdev;
dev_t dev = 0;
int open_adc = 1; //当变量为1时配置adc寄存器,为0时复位寄存器
struct class *adc_class;
typedef struct
{
int channel;
int prescale;
}MY_ADC_DEV;
MY_ADC_DEV adcdev;
int adc_open(struct inode *inode, struct file *filp)
{
printk(KERN_INFO "AD device opened\n");
unsigned int tmp;
base = ioremap(S3C6410_ADC_BASE,32);
if(open_adc)
{
adcdev.channel = 1;
adcdev.prescale= 0xff;
ADCCON = 0x00;
ADCCON = ((1<<14)|(adcdev.prescale<<6)|(adcdev.channel<<3)); /* A/D转换结束(启动预定标器),预分频值=0xff,输入通道为0 */
open_adc -= open_adc;
}
tmp = readl(S3C64XX_GPCCON);
printk("%d\n",tmp);
//tmp = (tmp & ~(0x7U<<1))|(0x1U);
tmp = (tmp | (0x01<<0) | (0x01<<4) | (0x01<<8) | (0x01<<12) | (0x01<<16) | (0x01<<20));
printk("---tmp---%d\n",tmp);
writel(tmp, S3C64XX_GPCCON);
//tmp = 0x00;
//tmp = (tmp | (0x3 <<4 ));
writel(0x30,S3C64XX_GPCDAT);
return 0;
}
static int adc_release(struct inode *node, struct file *file)
{
printk(KERN_INFO "AD device released\n");
ADCCON = 0x3fc4;
return 0;
}
ssize_t adc_read(struct file *file,char __user *buff,size_t count,loff_t *fops)
{
int val;
//char str[10]={0};
ADCCON |= 0x01; //开始转换
printk("xxxxxxxx\n");
while(!(ADCCON & 0x8000)); //不等于1.转换中
val = ADCDAT0 & 0x3ff;
printk("--xxxxxxxx--\n");
// sprintf(str,"%4d", val);
//printk(KERN_INFO "AD val = %d\n",val);
copy_to_user(buff,&val,4);
return 4;
}
ssize_t adc_write(struct file *filp, char __user *buff, size_t count, loff_t *fops)
{
char wbuf[4];
unsigned tmp;
printk("#########write######\n");
copy_from_user(wbuf,buff,count);
tmp = wbuf[0];
#if 1
switch(wbuf[0])
{
case 0x36: tmp = 0x36;printk("%d\n",wbuf[0]);writel(tmp, S3C64XX_GPCDAT); break;
case 0x3a: tmp = 0x3a;printk("%d\n",wbuf[0]); writel(tmp,S3C64XX_GPCDAT); break;
case 0x39: tmp = 0x39;printk("%d\n",wbuf[0]);writel(tmp, S3C64XX_GPCDAT); break;
case 0x35: tmp = 0x35;printk("%d\n",wbuf[0]);writel(tmp, S3C64XX_GPCDAT); break;
case 0x30: printk("reset\n");break;
default : break;
}
#endif
return count;
}
/* file_operation结构体 */
static struct file_operations adc_fops = {
.owner = THIS_MODULE,
.open = adc_open,
.release = adc_release,
.read = adc_read,
.write = adc_write,
//.ioctl = adc_ioctl,
};
/* ADC设备初始化 */
static void char_reg_setup_cdev (void)
{
int error;
cdev_init(&cdev,&adc_fops);
cdev.owner = THIS_MODULE;
cdev.ops = &adc_fops;
error = cdev_add(&cdev,dev,1);
if(error)
printk(KERN_NOTICE "Error %d adding char_reg_setup_cdev",error);
}
/* 加载ADC模块 */
static int adc_init(void)
{
int ret;
dev = MKDEV(adc_major,adc_minor);
if(adc_major)
{
ret = register_chrdev_region(dev,1,"adc");
//char_reg_setup_cdev();
}
else
{
ret = alloc_chrdev_region(&dev,0,1,"adc");
adc_major = MAJOR(dev);
}
char_reg_setup_cdev();
if(ret<0)
{
printk(KERN_WARNING "LED:unable to get major %d\n", adc_major);
return ret;
}
printk("ADC device installed,with major %d\n", adc_major);
adc_class = class_create(THIS_MODULE,"ad_class");
if (IS_ERR(adc_class))
{
printk("Err: failed in creating class.\n");
return 0;
}
device_create(adc_class, NULL, dev, NULL, "adc");
return 0;
}
/* 注销ADC模块 */
static void adc_exit(void)
{
//dev = MKDEV(adc_major,adc_minor);
device_destroy(adc_class,dev);
class_destroy(adc_class);
cdev_del(&cdev);
unregister_chrdev_region(dev,1);
iounmap(base);
printk("ADC device uninstalled\n");
}
module_init(adc_init);
module_exit(adc_exit);
MODULE_LICENSE("GPL");
- 1
- 2
前往页