⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s3c2410-adc.c

📁 UP-NETARM3000下教材实例源码,其中提供了多个实验内容源码,使用ARM相应开发环境即可
💻 C
字号:
/* * s3c2410-adc.c * * S3C2410 ADC  *  exclusive with s3c2410-ts.c * * Author: SeonKon Choi <bushi@mizi.com> * Date  : $Date: 2003/01/20 14:24:49 $  * * $Revision: 1.1.2.6 $ *	2004-6-14 add a device by threewater<threewater@up-tech.com>   Fri Dec 03 2002 SeonKon Choi <bushi@mizi.com>   - initial * * This file is subject to the terms and conditions of the GNU General Public * License.  See the file COPYING in the main directory of this archive * for more details. */#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/sched.h>#include <linux/irq.h>#include <linux/delay.h>#include <asm/hardware.h>#include <asm/semaphore.h>#include <asm/uaccess.h>#include "s3c2410-adc.h"#undef DEBUG//#define DEBUG#ifdef DEBUG#define DPRINTK(x...) {printk(__FUNCTION__"(%d): ",__LINE__);printk(##x);}#else#define DPRINTK(x...) (void)(0)#endif#define DEVICE_NAME	"s3c2410-adc"#define ADCRAW_MINOR	1static int adcMajor = 0;typedef struct {	struct semaphore lock;	wait_queue_head_t wait;	int channel;	int prescale;}ADC_DEV;static ADC_DEV adcdev;#define START_ADC_AIN(ch, prescale) \	do{ \		ADCCON = PRESCALE_EN | PRSCVL(prescale) | ADC_INPUT((ch)) ; \		ADCCON |= ADC_START; \	}while(0)static void adcdone_int_handler(int irq, void *dev_id, struct pt_regs *reg){	wake_up(&adcdev.wait);}static ssize_t s3c2410_adc_write(struct file *file, const char *buffer, size_t count, loff_t * ppos){	int data;	if(count!=sizeof(data)){		//error input data size		DPRINTK("the size of  input data must be %d\n", sizeof(data));		return 0;	}	copy_from_user(&data, buffer, count);	adcdev.channel=ADC_WRITE_GETCH(data);	adcdev.prescale=ADC_WRITE_GETPRE(data);	DPRINTK("set adc channel=%d, prescale=0x%x\n", adcdev.channel, adcdev.prescale);	return count;}static ssize_t s3c2410_adc_read(struct file *filp, char *buffer, size_t count, loff_t *ppos){	int ret = 0;	if (down_interruptible(&adcdev.lock))		return -ERESTARTSYS;	START_ADC_AIN(adcdev.channel, adcdev.prescale);	interruptible_sleep_on(&adcdev.wait);	ret = ADCDAT0;	ret &= 0x3ff;	DPRINTK("AIN[%d] = 0x%04x, %d\n", adcdev.channel, ret, ADCCON & 0x80 ? 1:0);	copy_to_user(buffer, (char *)&ret, sizeof(ret));	up(&adcdev.lock);	return sizeof(ret);}static int s3c2410_adc_open(struct inode *inode, struct file *filp){	init_MUTEX(&adcdev.lock);	init_waitqueue_head(&(adcdev.wait));	adcdev.channel=0;	adcdev.prescale=0xff;	MOD_INC_USE_COUNT;	DPRINTK( "adc opened\n");	return 0;}static int s3c2410_adc_release(struct inode *inode, struct file *filp){	MOD_DEC_USE_COUNT;	DPRINTK( "adc closed\n");	return 0;}static struct file_operations s3c2410_fops = {	owner:	THIS_MODULE,	open:	s3c2410_adc_open,	read:	s3c2410_adc_read,		write:	s3c2410_adc_write,	release:	s3c2410_adc_release,};#ifdef CONFIG_DEVFS_FSstatic devfs_handle_t devfs_adc_dir, devfs_adcraw;#endifint __init s3c2410_adc_init(void){	int ret;	/* normal ADC */	ADCTSC = 0; //XP_PST(NOP_MODE);	ret = request_irq(IRQ_ADC_DONE, adcdone_int_handler, SA_INTERRUPT, DEVICE_NAME, NULL);	if (ret) {		return ret;	}	ret = register_chrdev(0, DEVICE_NAME, &s3c2410_fops);	if (ret < 0) {		printk(DEVICE_NAME " can't get major number\n");		return ret;	}	adcMajor=ret;#ifdef CONFIG_DEVFS_FS	devfs_adc_dir = devfs_mk_dir(NULL, "adc", NULL);	devfs_adcraw = devfs_register(devfs_adc_dir, "0raw", DEVFS_FL_DEFAULT,				adcMajor, ADCRAW_MINOR, S_IFCHR | S_IRUSR | S_IWUSR, &s3c2410_fops, NULL);#endif	printk (DEVICE_NAME"\tinitialized\n");	return 0;}module_init(s3c2410_adc_init);#ifdef MODULEvoid __exit s3c2410_adc_exit(void){#ifdef CONFIG_DEVFS_FS		devfs_unregister(devfs_adcraw);	devfs_unregister(devfs_adc_dir);#endif	unregister_chrdev(adcMajor, DEVICE_NAME);	free_irq(IRQ_ADC_DONE, NULL);}module_exit(s3c2410_adc_exit);MODULE_LICENSE("GPL");#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -