linux 内核 pwm,s3c2410 linux2.6.14的内核pwm驱动

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include "s3c2410_pwm.h"

#define DEVICE_NAME    "pwm"

staticintpwm_major = 0;

staticintpwm_set_prescaler(structPWM_CHANNEL *pwm)

{

writel( (readl(S3C2410_TCFG0)&0xffffff00) + (pwm->prescaler0&0xFF) ,S3C2410_TCFG0 );

return0;

}

staticintpwm_set_channel(unsignedcharchannel,structPWM_CHANNEL *pwm)

{

unsigned longtmp;

unsigned longtmp1;

switch(channel)

{

case0:

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;

case1:

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;

case2:

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;

case3:

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;

}

return0;

}

staticintpwm_ioctl(structinode *inode,structfile *file, unsignedintcmd, unsignedlongarg)

{

structPWM_CHANNEL pwm;

switch(cmd)

{

casePWM_CHANNEL_0:

casePWM_CHANNEL_1:

casePWM_CHANNEL_2:

casePWM_CHANNEL_3:

if(copy_from_user(&pwm,(structPWM_CHANNEL *)arg,sizeof(structPWM_CHANNEL)))

return-EFAULT;

pwm_set_channel(cmd,&pwm);

break;

default:

return-EFAULT;

}

return0;

}

staticintpwm_open(structinode * inode,structfile * filp)

{

return0;

}

staticintpwm_release(structinode * inode,structfile * filp)

{

return0;

}

staticstructfile_operations pwm_fops = {

.owner = THIS_MODULE,

.ioctl = pwm_ioctl,

.open = pwm_open,

.release=pwm_release,

};

staticint__init pwm_init(void)

{

intret;

ret = register_chrdev(0,DEVICE_NAME,&pwm_fops);

if(ret 

{

printk("pwm: can't get major number\n");

returnret;

}

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");

returnret;

}

#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");

return0;

}

staticvoid__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");

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值