📄 adc.c
字号:
#include <linux/kernel.h>#include <linux/init.h>#include <linux/module.h>#include <linux/ioport.h>#include <linux/miscdevice.h> #include <linux/sched.h> #include <linux/delay.h> #include <linux/poll.h> #include <linux/spinlock.h> #include <linux/delay.h> #include <linux/wait.h>#include <linux/device.h> #include <linux/devfs_fs_kernel.h> #include <linux/types.h> #include <linux/cdev.h> #include <linux/errno.h> #include <asm/uaccess.h> #include <asm/hardware.h>#include <asm/io.h>#include <asm/arch/regs-mem.h>#include <asm/arch/regs-gpio.h>#include <asm/arch-s3c2410/regs-adc.h>#include <asm/arch-s3c2410/regs-clock.h>#include <asm-arm/arch-s3c2410/map.h>#include "adc.h"#define DEVICE_NAME "adc" static void __iomem *base_addr;static int adc_major = 0;static ssize_t adc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos){ int data; unsigned long tmp; //start ADC tmp = readl(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START; writel( tmp, base_addr+S3C2410_ADCCON); //state do { tmp = readl(base_addr+S3C2410_ADCCON); }while(!(((unsigned int)tmp)&0x8000)); //read data data = readl(base_addr+S3C2410_ADCDAT0) & 0x3ff; if(copy_to_user(buf, &data, sizeof(int))) return -EFAULT; return (sizeof(int));}static ssize_t adc_write(struct file * file, const char __user * buf, size_t count, loff_t * off){ unsigned long tmp; struct ADC_DEV adcdev; copy_from_user(&adcdev,(struct ADC_DEV *)buf,sizeof(struct ADC_DEV)); //S3C2410_CLKCON writel((readl(S3C2410_CLKCON) | S3C2410_CLKCON_ADC),S3C2410_CLKCON); //S3C2410_ADCTSC tmp = readl(base_addr+S3C2410_ADCTSC); tmp &= (~S3C2410_ADCTSC_AUTO_PST) | S3C2410_ADCTSC_XY_PST(S3C2410_NOP_MODE); writel(tmp , base_addr+S3C2410_ADCTSC); //S3C2410_ADCCON tmp = readl(base_addr+S3C2410_ADCCON); tmp = S3C2410_ADCCON_PRSCEN|S3C2410_ADCCON_PRSCVL(adcdev.prescale)|S3C2410_ADCCON_SELMUX(adcdev.channel); writel( tmp, base_addr+S3C2410_ADCCON); return 0;}static int adc_open(struct inode * inode, struct file * filp){ return 0;}static int adc_release(struct inode * inode, struct file * filp){ return 0;}static struct file_operations adc_fops = { .owner = THIS_MODULE, .write = adc_write, .read = adc_read, .open = adc_open, .release=adc_release,}; static int __init adc_init(void){ int ret; ret = register_chrdev(0,DEVICE_NAME,&adc_fops); if(ret < 0) { printk("adc: can't get major number\n"); return ret; } adc_major = ret;#ifdef CONFIG_DEVFS_FS ret = devfs_mk_cdev(MKDEV(adc_major,0), S_IFCHR | S_IRUGO | S_IWUSR,DEVICE_NAME); if(ret) { unregister_chrdev(adc_major,DEVICE_NAME); printk("adc: can't make char device fo devfs\n"); return ret; }#endif base_addr=ioremap(S3C2410_PA_ADC,4); if (base_addr == NULL) { printk(KERN_ERR "Failed to remap register block\n"); return -ENOMEM; } printk("s3c2410_adc driver initial\n"); return 0;}static void __exit adc_exit(void){#ifdef CONFIG_DEVFS_FS devfs_remove(DEVICE_NAME);#endif unregister_chrdev(adc_major,DEVICE_NAME); iounmap(base_addr); printk("s3c2410_adc driver removed\n"); }module_init(adc_init);module_exit(adc_exit);MODULE_ALIAS("adc"); MODULE_DESCRIPTION("ADC IO Driver For EM104-MINI2410");MODULE_AUTHOR("LIANXJ");MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -