/****************************************************************************
* OK335xS pwm buzzer Linux driver hacking
* 声明:
* 本文仅仅是为了知道如何使用pwm来控制buzzer,已达到控制不同声音的频率。
*
* 2015-10-7 雨 深圳 南山平山村 曾剑锋
***************************************************************************/
#include <linux/init.h>
#include <linux/export.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/types.h>
#include <linux/io.h>
#include <linux/pwm/pwm.h>
#include <linux/fs.h>
#define DEBUG
#if defined(DEBUG)
#define DPRINTK(fmt,arg...) printk(fmt,##arg);
#else
#define DPRINTK(fmt,arg...)
#endif
#define BUZZER_FREQENCY 1
#define DEV_NAME "buzzer"
/*pwm for this buzzer*/
struct pwm_device *pwm = NULL;
static int buzzer_open(struct inode *inode, struct file *filp)
{
if(pwm != NULL)
return -EBUSY;
/**
* 申请一个pwm设备
*/
pwm = pwm_request("ecap.1", -, "buzzer");
if ( pwm == NULL ) {
printk("buzzer open error.\n");
}
printk("buzzer open\n");
return ;
}
static int buzzer_release(struct inode *inode, struct file *filp)
{
/**
* 关闭、注销一个pwm设备
*/
pwm_stop(pwm);
pwm_release(pwm);
pwm = NULL;
printk("buzzer release\n");
return ;
}
static long buzzer_ioctl(struct file *filp,
unsigned int cmd, unsigned long arg)
{
if(pwm == NULL)
return -EINVAL;
if(arg > || arg < )
return -EINVAL;
switch (cmd) {
case BUZZER_FREQENCY: // 设置频率
if(arg==)
pwm_stop(pwm);
else
{
pwm_set_period_ns(pwm, /arg);
pwm_set_duty_ns(pwm, );
pwm_start(pwm);
}
break;
default:
break;
}
return ;
}
static struct file_operations buzzer_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = buzzer_ioctl,
.open = buzzer_open,
.release = buzzer_release,
};
static struct miscdevice buzzer_miscdev =
{
.minor = MISC_DYNAMIC_MINOR,
.name = DEV_NAME,
.fops = &buzzer_fops,
};
static int __init buzzer_init(void)
{
/**
* 注册杂项设备
*/
misc_register(&buzzer_miscdev);
return ;
}
static void __exit buzzer_exit(void)
{
misc_deregister(&buzzer_miscdev);
}
module_init(buzzer_init);
module_exit(buzzer_exit);