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

📄 s3c2410_pwm.c

📁 ARM s3c2410 linux2.6下的pwd驱动.
💻 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-timer.h>#include "s3c2410_pwm.h"#define DEVICE_NAME			"pwm" static int pwm_major = 0;static int pwm_set_prescaler(struct PWM_CHANNEL *pwm){	writel( (readl(S3C2410_TCFG0)&0xffffff00) + (pwm->prescaler0&0xFF) ,S3C2410_TCFG0 );		return 0;}static int pwm_set_channel(unsigned char channel,struct PWM_CHANNEL *pwm){		unsigned long tmp;	unsigned long tmp1;	switch(channel)	{		case 0:			pwm_set_prescaler(pwm);			tmp = readl(S3C2410_TCFG1); 			tmp = (tmp & (~(0x0F<<0))) | ((pwm->div_clock&0x000F)<<0);			writel(tmp, S3C2410_TCFG1);			writel((pwm->tcntb_reg&0xFFFF), S3C2410_TCNTB(channel));			writel((pwm->tcmpb_reg&0xFFFF), S3C2410_TCMPB(channel));						tmp = readl(S3C2410_TCON) | S3C2410_TCON_T0RELOAD | S3C2410_TCON_T0MANUALUPD;			tmp1 = (readl(S3C2410_TCON) | S3C2410_TCON_T0RELOAD) & (~S3C2410_TCON_T0MANUALUPD);			writel(tmp, S3C2410_TCON);			if(pwm->off)				writel(tmp1&(~S3C2410_TCON_T0START), S3C2410_TCON);				else				writel(tmp1 | S3C2410_TCON_T0START, S3C2410_TCON);						break;			case 1:			pwm_set_prescaler(pwm);			tmp = readl(S3C2410_TCFG1);			tmp = (tmp & (~(0x0F<<4))) | ((pwm->div_clock&0x000F)<<4);			writel(tmp, S3C2410_TCFG1);			writel((pwm->tcntb_reg&0xFFFF), S3C2410_TCNTB(channel));			writel((pwm->tcmpb_reg&0xFFFF), S3C2410_TCMPB(channel));						tmp = readl(S3C2410_TCON) | S3C2410_TCON_T1RELOAD | S3C2410_TCON_T1MANUALUPD;			tmp1 = (readl(S3C2410_TCON) | S3C2410_TCON_T1RELOAD) & (~S3C2410_TCON_T1MANUALUPD);			writel(tmp, S3C2410_TCON);						if(pwm->off)				writel(tmp1 & (~S3C2410_TCON_T1START), S3C2410_TCON);				else				writel(tmp1 | S3C2410_TCON_T1START, S3C2410_TCON);							break;		case 2:			tmp = readl(S3C2410_TCFG1);			tmp = (tmp & (~(0x0F<<8))) | ((pwm->div_clock&0x000F)<<8);			writel(tmp, S3C2410_TCFG1);			writel(pwm->tcntb_reg&0xFFFF, S3C2410_TCNTB(channel));			writel(pwm->tcmpb_reg&0xFFFF, S3C2410_TCMPB(channel));						tmp = readl(S3C2410_TCON) | S3C2410_TCON_T2RELOAD | S3C2410_TCON_T2MANUALUPD;			tmp1 = (readl(S3C2410_TCON) | S3C2410_TCON_T2RELOAD) & (~S3C2410_TCON_T2MANUALUPD);			writel(tmp, S3C2410_TCON);						if(pwm->off)				writel(tmp1 & (~S3C2410_TCON_T2START), S3C2410_TCON);				else				writel(tmp1 | S3C2410_TCON_T2START, S3C2410_TCON);							break;				case 3:			tmp = readl(S3C2410_TCFG1);			tmp = (tmp & (~(0x0F<<12))) | ((pwm->div_clock&0x000F)<<12);			writel(tmp, S3C2410_TCFG1);			writel(pwm->tcntb_reg&0xFFFF, S3C2410_TCNTB(channel));			writel(pwm->tcmpb_reg&0xFFFF, S3C2410_TCMPB(channel));						tmp = readl(S3C2410_TCON) | S3C2410_TCON_T3RELOAD | S3C2410_TCON_T3MANUALUPD;			tmp1 = (readl(S3C2410_TCON) | S3C2410_TCON_T3RELOAD) & (~S3C2410_TCON_T3MANUALUPD);			writel(tmp, S3C2410_TCON);						if(pwm->off)				writel(tmp1 & (~S3C2410_TCON_T3START), S3C2410_TCON);				else				writel(tmp1 | S3C2410_TCON_T3START, S3C2410_TCON);							break;						default:			break;	}	return 0;}static int pwm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){	struct PWM_CHANNEL pwm;	switch(cmd)	{		case PWM_CHANNEL_0:		case PWM_CHANNEL_1:		case PWM_CHANNEL_2:		case PWM_CHANNEL_3:			if(copy_from_user(&pwm,(struct PWM_CHANNEL *)arg,sizeof(struct PWM_CHANNEL))) 	    		return -EFAULT;				pwm_set_channel(cmd,&pwm);			break;		default:			return -EFAULT;		}	return 0;}static int pwm_open(struct inode * inode, struct file * filp){	return 0;}static int pwm_release(struct inode * inode, struct file * filp){	return 0;}static struct file_operations pwm_fops = { 	.owner = THIS_MODULE, 	.ioctl = pwm_ioctl, 	.open  = pwm_open,	.release=pwm_release,}; static int __init pwm_init(void){	int ret;		ret = register_chrdev(0,DEVICE_NAME,&pwm_fops);  	if(ret < 0) 	{		printk("pwm: can't get major number\n");       	return ret;	}	pwm_major = ret;#ifdef CONFIG_DEVFS_FS       ret = devfs_mk_cdev(MKDEV(pwm_major,0),  S_IFCHR | S_IRUGO | S_IWUSR,DEVICE_NAME);	if(ret)	{		unregister_chrdev(pwm_major,DEVICE_NAME); 		printk("pwm: can't make char device fo devfs\n");		return ret;	}#endif	s3c2410_gpio_cfgpin(S3C2410_GPB0,S3C2410_GPB0_TOUT0); 	s3c2410_gpio_cfgpin(S3C2410_GPB1,S3C2410_GPB1_TOUT1);	s3c2410_gpio_cfgpin(S3C2410_GPB2,S3C2410_GPB2_TOUT2); 	s3c2410_gpio_cfgpin(S3C2410_GPB3,S3C2410_GPB3_TOUT3);  	    printk("s3c2410_pwm driver initial\n");    	return 0;}static void __exit pwm_exit(void){#ifdef CONFIG_DEVFS_FS	devfs_remove(DEVICE_NAME);#endif  	unregister_chrdev(pwm_major,DEVICE_NAME);     printk("s3c2410_pwm driver removed\n"); }module_init(pwm_init);module_exit(pwm_exit);MODULE_ALIAS("pwm"); MODULE_DESCRIPTION("PWM IO Driver For EM104-MINI2410");MODULE_AUTHOR("LIANXJ");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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