ARM11 硬件 PWM驱动蜂鸣器设备代码
2013-10-08 10:21
447 查看
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <mach/hardware.h>
#include <plat/regs-timer.h>
#include <mach/regs-irq.h>
#include <asm/mach/time.h>
#include <linux/clk.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
#include <mach/map.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>
#include <plat/gpio-cfg.h>
#include <mach/gpio.h>
#include <mach/gpio-bank-f.h>
#define device_name "misc_pwm"
#define command_set_freq 0
#define command_stop 1
static struct semaphore flag;
static void PWM_set_freq(unsigned long freq)
{
unsigned long tcon;
unsigned long tcnt;
unsigned long tcfg0;
unsigned long tcfg1;
struct clk *clk_pointer;
unsigned long pclk;
s3c_gpio_cfgpin(S3C64XX_GPF(14),S3C64XX_GPF14_PWM_TOUT0);
tcon = __raw_readl(S3C_TCON);
tcfg0 = __raw_readl(S3C_TCFG0);
tcfg1 = __raw_readl(S3C_TCFG1);
tcfg0 &= ~(S3C_TCFG_PRESCALER0_MASK);
tcfg0 |= 1;
__raw_writel(tcfg0,S3C_TCFG0);
tcfg1 &= ~(S3C_TCFG1_MUX0_MASK);
tcfg1 |= S3C_TCFG1_MUX0_DIV1;
__raw_writel(tcfg1,S3C_TCFG1);
clk_pointer = clk_get(NULL,"pclk");
pclk = clk_get_rate(clk_pointer);
tcnt = (pclk/1/1)/freq;
__raw_writel(tcnt, S3C_TCNTB(0));
__raw_writel(tcnt/2, S3C_TCMPB(0));
tcon &= ~0x1f;
tcon |= 0xb; //disable deadzone, auto-reload, inv-off, update TCNTB0&TCMPB0, start timer 0
__raw_writel(tcon, S3C_TCON);
tcon &= ~2; //clear manual update bit
__raw_writel(tcon, S3C_TCON);
}
void PWM_Stop(void)
{
s3c_gpio_cfgpin(S3C64XX_GPF(14),S3C_GPIO_INPUT);
__raw_writel(0x00,S3C_TCON);
}
static int PWM_open(struct inode *inode, struct file *filp)
{
if(!down_trylock(&flag))
{
return 0;
}
else
{
return -EBUSY;
}
}
static int PWM_release(struct inode *inode,struct file *filp)
{
up(&flag);
return 0;
}
static long PWM_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
switch(cmd)
{
case command_set_freq:
PWM_set_freq(arg);
break;
case command_stop:
PWM_Stop();
break;
default:
PWM_Stop();
break;
}
return 0;
}
static struct file_operations PWM_fops = {
.owner = THIS_MODULE,
.open = PWM_open,
.release = PWM_release,
.unlocked_ioctl = PWM_unlocked_ioctl,
};
static struct miscdevice miscpwm = {
.minor = MISC_DYNAMIC_MINOR,
.name = device_name,
.fops = &PWM_fops,
};
int pwm_up_init(void)
{
int ret;
sema_init(&flag,1);
ret = misc_register(&miscpwm);
if(ret < 0)
{
printk("the pwm has unmodule \n");
}
printk("the pwm has registered \n");
return 0;
}
void pwm_exit(void)
{
misc_deregister(&miscpwm);
printk("the pwm has exit\n");
}
module_init(pwm_up_init);
module_exit(pwm_exit);
MODULE_LICENSE("GPL");
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <mach/hardware.h>
#include <plat/regs-timer.h>
#include <mach/regs-irq.h>
#include <asm/mach/time.h>
#include <linux/clk.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
#include <mach/map.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>
#include <plat/gpio-cfg.h>
#include <mach/gpio.h>
#include <mach/gpio-bank-f.h>
#define device_name "misc_pwm"
#define command_set_freq 0
#define command_stop 1
static struct semaphore flag;
static void PWM_set_freq(unsigned long freq)
{
unsigned long tcon;
unsigned long tcnt;
unsigned long tcfg0;
unsigned long tcfg1;
struct clk *clk_pointer;
unsigned long pclk;
s3c_gpio_cfgpin(S3C64XX_GPF(14),S3C64XX_GPF14_PWM_TOUT0);
tcon = __raw_readl(S3C_TCON);
tcfg0 = __raw_readl(S3C_TCFG0);
tcfg1 = __raw_readl(S3C_TCFG1);
tcfg0 &= ~(S3C_TCFG_PRESCALER0_MASK);
tcfg0 |= 1;
__raw_writel(tcfg0,S3C_TCFG0);
tcfg1 &= ~(S3C_TCFG1_MUX0_MASK);
tcfg1 |= S3C_TCFG1_MUX0_DIV1;
__raw_writel(tcfg1,S3C_TCFG1);
clk_pointer = clk_get(NULL,"pclk");
pclk = clk_get_rate(clk_pointer);
tcnt = (pclk/1/1)/freq;
__raw_writel(tcnt, S3C_TCNTB(0));
__raw_writel(tcnt/2, S3C_TCMPB(0));
tcon &= ~0x1f;
tcon |= 0xb; //disable deadzone, auto-reload, inv-off, update TCNTB0&TCMPB0, start timer 0
__raw_writel(tcon, S3C_TCON);
tcon &= ~2; //clear manual update bit
__raw_writel(tcon, S3C_TCON);
}
void PWM_Stop(void)
{
s3c_gpio_cfgpin(S3C64XX_GPF(14),S3C_GPIO_INPUT);
__raw_writel(0x00,S3C_TCON);
}
static int PWM_open(struct inode *inode, struct file *filp)
{
if(!down_trylock(&flag))
{
return 0;
}
else
{
return -EBUSY;
}
}
static int PWM_release(struct inode *inode,struct file *filp)
{
up(&flag);
return 0;
}
static long PWM_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
switch(cmd)
{
case command_set_freq:
PWM_set_freq(arg);
break;
case command_stop:
PWM_Stop();
break;
default:
PWM_Stop();
break;
}
return 0;
}
static struct file_operations PWM_fops = {
.owner = THIS_MODULE,
.open = PWM_open,
.release = PWM_release,
.unlocked_ioctl = PWM_unlocked_ioctl,
};
static struct miscdevice miscpwm = {
.minor = MISC_DYNAMIC_MINOR,
.name = device_name,
.fops = &PWM_fops,
};
int pwm_up_init(void)
{
int ret;
sema_init(&flag,1);
ret = misc_register(&miscpwm);
if(ret < 0)
{
printk("the pwm has unmodule \n");
}
printk("the pwm has registered \n");
return 0;
}
void pwm_exit(void)
{
misc_deregister(&miscpwm);
printk("the pwm has exit\n");
}
module_init(pwm_up_init);
module_exit(pwm_exit);
MODULE_LICENSE("GPL");
相关文章推荐
- PWM控制蜂鸣器驱动详细概念及代码
- OK6410之蜂鸣器驱动硬件分析---PWM定时器
- mini2440 pwm蜂鸣器设备驱动开发源代码(宋宝华框架)
- 字符设备驱动之蜂鸣器与PWM——FS2410
- usb转rs232驱动无效,已经电脑自动扫描检测硬件改动.设备无法运行错误代码10
- ARM11 paltform驱动代码完成,最简单的测试直接在装载设备中运行,实现秒读
- Linux查看硬件信息以及驱动设备的命令
- Linux下的硬件驱动——USB设备(下)
- Linux I2C Input设备驱动代码的几点理解
- ok6410学习笔记(9.混杂设备驱动及硬件访问)
- 音频设备驱动代码单独存放于sound/目录而不在drivers/目录中
- Linux网络管理员手册(3) 第三章 配置网络硬件 设备、驱动程序 内核配置 支持的板卡 PLIP驱动 SLIP和PPP驱动程序
- 【Espruino】NO.08 使用PWM驱动蜂鸣器奏乐
- Linux下的硬件驱动——USB设备(上)(驱动配置部分)
- platform平台设备驱动简化示例代码
- Linux下的硬件驱动——USB设备(上)(驱动配置部分)
- 宋宝华 《Linux设备驱动开发详解》示例代码之基本字符设备驱动
- 字符设备驱动代码完整分析
- 【Tiny6410 And Linux】—(2.1)—platform 总线、设备、驱动——代码
- 蜂鸣器驱动代码