OK335xS pwm buzzer Linux driver hacking

简介: /**************************************************************************** * OK335xS pwm buzzer Linux driver hacking * 声明: * 本文仅仅是为了知道如何使用pwm来控制buzzer,已达到控制不同声音的频率。
/****************************************************************************
 *                 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", -1, "buzzer");
    if ( pwm == NULL ) {
        printk("buzzer open error.\n");
    }

    printk("buzzer open\n");
    return 0;
}

static int buzzer_release(struct inode *inode, struct file *filp)
{
    /**
     * 关闭、注销一个pwm设备
     */
    pwm_stop(pwm);
    pwm_release(pwm);
    pwm = NULL;

    printk("buzzer release\n");

    return 0;
}


static long buzzer_ioctl(struct file *filp,
                        unsigned int cmd, unsigned long arg)
{

    if(pwm == NULL)
        return -EINVAL;

    if(arg > 20000 || arg < 0)
        return -EINVAL;

    switch (cmd) {
    case BUZZER_FREQENCY:       // 设置频率
        if(arg==0)
            pwm_stop(pwm);
        else
        {
            pwm_set_period_ns(pwm, 1000000000/arg);
            pwm_set_duty_ns(pwm, 25000);
            pwm_start(pwm);
        }
        
        break;
    default:
        break;
    }

    return 0;
}

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 0;
}

static void __exit buzzer_exit(void)
{
   misc_deregister(&buzzer_miscdev);
}

module_init(buzzer_init);
module_exit(buzzer_exit);

 

目录
相关文章
|
Linux SoC API
linux中serial driver理解【转】
转自:http://blog.csdn.net/laoliu_lcl/article/details/39967225 英文文档地址:myandroid/kernel_imx/Documentation/serialg/driver。
1060 0
|
Linux
hacking a friend&#39;s Linux buzzer driver in OK335xS
1 /**************************************************************************** 2 * hacking a friend's Linux buzzer driver in OK335xS 3 * 说明: 4 * 解读朋友的Linux buzzer驱动,作为后续相关编码的参考。
1131 0
|
Linux
OK335xS Linux Qt make: icpc: Command not found
      OK335xS Linux Qt make: icpc: Command not found   一、出错现象:   make: icpc: Command not found   make: *** [main.
1689 0
|
Shell Linux Perl
OK335xS U-boot 编译问题&无Linux shell 问题
/************************************************************************** * OK335xS U-boot 编译问题&无Linux shell 问题 * 声明: * 主要是因为系统之前是由本人师傅做的,他去掉了一些信息,同时由于他本人 * 目前不在旁边,在参考一些文件的时候出现以下情况。
959 0
|
Linux
Linux driver 板级文件跟踪一般方法
/*********************************************************************************** * Linux driver 板级文件跟踪一般方法 * 声明: * 1.
857 0