zoukankan      html  css  js  c++  java
  • OK335xS pwm buzzer Linux driver hacking

    /****************************************************************************
     *                 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.
    ");
        }
    
        printk("buzzer open
    ");
        return 0;
    }
    
    static int buzzer_release(struct inode *inode, struct file *filp)
    {
        /**
         * 关闭、注销一个pwm设备
         */
        pwm_stop(pwm);
        pwm_release(pwm);
        pwm = NULL;
    
        printk("buzzer release
    ");
    
        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);
  • 相关阅读:
    c++教程目录
    ANDROID教程目录
    ArrayBuffer
    读懂 ECMAScript 规格
    编程风格
    Module 的加载实现
    Module 的语法
    修饰器Decorator
    Class 的继承
    SQL Server 2008 R2导出数据脚本的方法
  • 原文地址:https://www.cnblogs.com/zengjfgit/p/4858612.html
Copyright © 2011-2022 走看看