linux驱动开发之pwm蜂鸣器

驱动开发,控制pwm蜂鸣器!
蜂鸣器有多种类型,一种是给电就叫,另一种给电了还不行,还需要freq才会叫。大概称作有源和无源吧!

我们此时将buzzer的驱动加入到内核中去。

/*
 * linux/drivers/char/smart210_pwm.c
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/fb.h>
#include <linux/backlight.h>
#include <linux/err.h>
#include <linux/pwm.h>
#include <linux/slab.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/gpio.h>

#include <mach/gpio.h>
#include <mach/regs-gpio.h>
#include <plat/gpio-cfg.h>


#define DEVICE_NAME             "pwm-buzzer"


#define PWM_IOCTL_STOP          0
#define PWM_IOCTL_SET_FREQ      1
#define PWM_IOCTL_SET_DUTY      2

#define NS_IN_1HZ               (1000000000UL)


#define BUZZER_PWM_ID           0
#define BUZZER_PMW_GPIO         S5PV210_GPD0(0)

static struct pwm_device *pwm0buzzer;

static struct semaphore lock;


static void pwm_set_freq(unsigned long freq) {
    int period_ns = NS_IN_1HZ / freq;

    pwm_config(pwm0buzzer, period_ns / 2, period_ns);
    pwm_enable(pwm0buzzer);

    s3c_gpio_cfgpin(BUZZER_PMW_GPIO, S3C_GPIO_SFN(2));
}

static void pwm_stop(void) {
    s3c_gpio_cfgpin(BUZZER_PMW_GPIO, S3C_GPIO_OUTPUT);

    pwm_config(pwm0buzzer, 0, NS_IN_1HZ / 100);
    pwm_disable(pwm0buzzer);
}


static int smart210_pwm_open(struct inode *inode, struct file *file) {
    if (!down_trylock(&lock))
        return 0;
    else
        return -EBUSY;
}

static int smart210_pwm_close(struct inode *inode, struct file *file) {
    up(&lock);
    return 0;
}

static long smart210_pwm_ioctl(struct file *filep, unsigned int cmd,
        unsigned long arg)
{
    switch (cmd) {
        case PWM_IOCTL_SET_FREQ:
            if (arg == 0)
                return -EINVAL;
            pwm_set_freq(arg);
            break;

        case PWM_IOCTL_STOP:
        case PWM_IOCTL_SET_DUTY:
        default:
            pwm_stop();
            break;
    }

    return 0;
}


static struct file_operations smart210_pwm_ops = {
    .owner          = THIS_MODULE,
    .open           = smart210_pwm_open,
    .release        = smart210_pwm_close, 
    .unlocked_ioctl = smart210_pwm_ioctl,
};

static struct miscdevice smart210_misc_dev = {
    .minor = MISC_DYNAMIC_MINOR,
    .name = DEVICE_NAME,
    .fops = &smart210_pwm_ops,


};

static int __init smart210_pwm_dev_init(void) {
    int ret;

    ret = gpio_request(BUZZER_PMW_GPIO, DEVICE_NAME);
    if (ret) {
        printk("request GPIO %d for pwm failed\n", BUZZER_PMW_GPIO);
        return ret;
    }

    gpio_set_value(BUZZER_PMW_GPIO, 0);
    s3c_gpio_cfgpin(BUZZER_PMW_GPIO, S3C_GPIO_OUTPUT);

    pwm0buzzer = pwm_request(BUZZER_PWM_ID, DEVICE_NAME);
    if (IS_ERR(pwm0buzzer)) {
        printk("request pwm %d for %s failed\n", BUZZER_PWM_ID, DEVICE_NAME);
        return -ENODEV;
    }

    pwm_stop();

    sema_init(&lock, 1);
    ret = misc_register(&smart210_misc_dev);

    printk(DEVICE_NAME "\tinitialized\n");

    return ret;
}

static void __exit smart210_pwm_dev_exit(void) {
    pwm_stop();

    misc_deregister(&sma
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值