s3c2410 A/D驱动
2012-03-05 13:37
155 查看
#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/cdev.h> #include <linux/device.h> #include <linux/io.h> #include <linux/irq.h> #include <linux/interrupt.h> #include <asm/uaccess.h> #include <linux/clk.h> #include <linux/wait.h> #include <linux/delay.h> #include <linux/sched.h> #define DEVICE_NAME "adc_driver" #define pADCCON 0x58000000 #define pADCDAT0 0x5800000C MODULE_LICENSE ("GPL"); unsigned long *vADCCON; /*ADC控制寄存器地址*/ unsigned long *vADCDAT0;/*ADCDAT0寄存器地址*/ int major = 250; int minor = 0; struct class *my_class; wait_queue_head_t my_queue; int sleep_flag = 0; int number_of_devices = 1; struct cdev cdev; dev_t devno = 0; /* open 打开设备 */ static int adc_driver_open(struct inode *inode, struct file *file) { struct clk *adc_clock = clk_get(NULL, "adc"); /*获得adc时钟*/ if (adc_clock == NULL) { printk(KERN_WARNING "clk_get failed"); return -ENOENT; } clk_enable(adc_clock); /*时能ADC时钟,打开ADC*/ writel((1<<14)|(49<<6)|(0x00),vADCCON); printk (KERN_INFO "adc_driver is open"); return 0; } static int adc_driver_release(struct inode *inode, struct file *file) { struct clk *adc_clock = clk_get(NULL, "adc"); clk_disable(adc_clock); return 0; } /*中断处理函数(ADC 可以使用中断方式和轮询方式获得转换好的数据)*/ irqreturn_t interrupt_adc(int irq, void *dev_id) { sleep_flag = 1; wake_up_interruptible(&my_queue); return IRQ_HANDLED; } /*阻塞读*/ static ssize_t adc_driver_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) { unsigned int num, ret; writel((readl(vADCCON) & ~(0x3)) | (0x1),vADCCON); wait_event_interruptible(my_queue, (sleep_flag == 1)); sleep_flag = 0; num = readl(vADCDAT0) & (0x3FF); ret = copy_to_user(buf, &num, sizeof(unsigned int)); if (ret < 0) printk (KERN_WARNING "copy_to_user failed"); return ret; } struct file_operations adc_fops = { .owner = THIS_MODULE, .open = adc_driver_open, .release = adc_driver_release, .read = adc_driver_read, }; 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, devno , 1); if (error) printk (KERN_NOTICE "Error %d adding char_reg_setup_cdev\n", error); } static int __init adc_driver_init (void) { int result; if (major) { devno = MKDEV(major,0); result = register_chrdev_region(devno,number_of_devices,DEVICE_NAME); } else result = alloc_chrdev_region(&devno, 0, number_of_devices, DEVICE_NAME); if (result < 0) { printk(KERN_WARNING "adc_driver: can't get major number %d\n", major); return result; } vADCCON = ioremap(pADCCON, 4); if (vADCCON == NULL) { printk("ioremap vADCCON failed"); return -1; } vADCDAT0 = ioremap(pADCDAT0, 4); if (vADCDAT0 == NULL) { printk("ioremap vADCDAT0 failed"); goto err0; } init_waitqueue_head(&my_queue); result = request_irq(IRQ_ADC, interrupt_adc, IRQF_DISABLED, "adc", NULL); if (result < 0) { printk (KERN_WARNING "request irq interrupt_adc failed\n"); } my_class = class_create( THIS_MODULE, "adc_class" ); if(IS_ERR(my_class)) { printk("Err: failed to create class.\n"); return -1; } device_create( my_class, NULL, devno, NULL, "adc_device"); char_reg_setup_cdev (); printk (KERN_INFO "char device registered\n"); return 0; err0: iounmap(vADCDAT0); return -1; } static void __exit adc_driver_exit (void) { iounmap(vADCCON); iounmap(vADCDAT0); free_irq(IRQ_ADC, NULL); device_destroy(my_class, devno); class_destroy(my_class); cdev_del (&cdev); unregister_chrdev_region (devno, number_of_devices); printk (KERN_INFO "adc_driver is clean up\n"); } module_init (adc_driver_init); module_exit (adc_driver_exit);
相关文章推荐
- 基于S3C2410的SD卡linux驱动工作原理(二)
- s3c2410 4X4矩阵键盘驱动
- s3c2410 RTC驱动框架linux内核源码分析
- s3c2410触摸屏驱动(2.6内核)分析
- s3c2410触摸屏驱动(2.6内核)分析 -中断下半部
- S3C2410 LCD驱动学习心得(三)
- s3c2410_lcd & frame buffer 驱动分析 int __init s3c2410fb_probe(struct device *dev) { struct s3c2410f
- linux s3c2410触摸屏驱动讲解
- 基于S3C2410平台移植Linux 2.6.14内核&驱动指南
- 基于S3C2410平台的Linux 2.6.14内核+平台驱动的移植指南(最终版)
- Linux设备驱动工程师之路——触摸屏驱动s3c2410_ts.c分析
- 触摸屏驱动s3c2410_ts.c分析
- s3c2410_i2c总线驱动及at24c02设备驱动实例
- Linux设备驱动工程师之路——触摸屏驱动s3c2410_ts.c分析
- s3c2410触摸屏驱动
- s3c2410矩阵键盘驱动
- S3c2410 LCD驱动学习心得 (转)
- 一个基于linux2.6内核下S3C2410触摸屏驱动
- 基于S3C2410的SD卡linux驱动工作原理
- 基于S3C2410的SD卡linux驱动工作原理(一)