#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
MODULE_LICENSE("GPL");
#define ADCCON 0x5800000
static struct resource adc_resource[] = {
[0] = {
.start = ADCCON,
.end = ADCCON + 8,
.flags = IORESOURCE_MEM,//地址类型的资源
},
[1] = {
.start = ADCCON,
.end = ADCCON+8,
.flags = IORESOURCE_IRQ,//中断类型的资源
},
};
struct platform_device key_device = {
.name = "MY-ADC",
.id = 0,
.num_resources = ARRAY_SIZE(adc_resource),
.resource = adc_resource,
};
static int button_init()
{
platform_device_register(&key_device);
return 0;
}
static void button_exit()
{
platform_device_unregister(&key_device);
}
module_init(button_init);
module_exit(button_exit);
#include <linux/module.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/fs.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/io.h>
static int major = 237;
static wait_queue_head_t wq;
static int have_data = 0;
static int adc;
static struct resource *res1;
static struct resource *res2;
static void *adc_base;
#define ADCCON 0x00000
#define ADCDLY 0x00008
#define ADCDAT 0x0000C
static irqreturn_t adc_handler(int irqno, void *dev)
{
int a;
have_data = 1;
printk("11111\n");
a=readl(adc_base + ADCCON);
if((a>>15)==0x1)
wake_up_interruptible(&wq);
return IRQ_HANDLED;
}
static int adc_open (struct inode *inod, struct file *filep)
{
return 0;
}
static ssize_t adc_read(struct file *filep, char __user *buf, size_t len, loff_t *pos)
{
writel(0X0000,adc_base +ADCCON );
writel(1<<0 | 1<<14 | 0X0<<3 | 0X31<<6 ,adc_base +ADCCON );
wait_event_interruptible(wq, have_data==1);
mdelay(100);
/*read data*/
adc = readl(adc_base+ADCDAT);
printk("%d",adc);
// adc = adc&0x3f;
if(copy_to_user(buf,&adc,sizeof(int)))
{
return -EFAULT;
}
have_data = 0;
return len;
}
static int adc_release(struct inode *inode, struct file *filep)
{
return 0;
}
static struct file_operations adc_ops =
{
.open = adc_open,
.release = adc_release,
.read = adc_read,
};
static int hello_probe(struct platform_device *pdev)
{
int ret;
printk("match 0k \n");
res1 = platform_get_resource(pdev,IORESOURCE_IRQ, 0);
res2 = platform_get_resource(pdev,IORESOURCE_MEM, 0);
ret = request_irq(res1->start,adc_handler,IRQF_DISABLED,"adc1",NULL);
adc_base = ioremap(res2->start,res2->end-res2->start);
register_chrdev( major, "adc", &adc_ops);
init_waitqueue_head(&wq);
return 0;
}
static int hello_remove(struct platform_device *pdev)
{
free_irq(res1->start,NULL);
free_irq(res2->start,NULL);
unregister_chrdev( major, "adc");
return 0;
}
/*
static struct of_device_id adc_id[]=
{
{.compatible = "fs4412,adc" },
};
*/
static struct platform_driver hello_driver=
{
.probe = hello_probe,
.remove = hello_remove,
.driver ={
.name = "MY-ADC",
.owner = THIS_MODULE,
},
};
static int hello_init(void)
{
printk("hello_init");
return platform_driver_register(&hello_driver);
}
static void hello_exit(void)
{
platform_driver_unregister(&hello_driver);
printk("hello_exit \n");
return;
}
MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
main()
{
int fd,len;
int adc=0;
fd = open("/dev/adc",O_RDWR);
if(fd<0)
{
perror("open fail \n");
return ;
}
while(1)
{
read(fd,&adc,4);
adc= adc<<12;
adc= adc>>12;
// adc= adc>>8;
printf("adc%0.2f V \n",(1.8*adc)/51314);
// printf("adc%x V \n",adc);
sleep(2);
}
close(fd);