⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 beep.c

📁 这是一个在linux下的蜂鸣器的程序
💻 C
字号:
/************************************************************
Copyright (C), 2005-2010, Embedded System of China Tech. Co., Ltd.
    www.emsyschina.com
FileName: Beep.c
Author: Version : Date: Casiawu(wujh@emsyschina.com)
Description: // 蜂鸣器驱动程序模块
1. -------
History: // 历史修改记录
<author> <time> <version > <desc>
casiawu 2008/2/12 1.0 build this module for linux (2.6.21)
***********************************************************/

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/timer.h>
#include <linux/kdev_t.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/platform_device.h>

#include <asm/uaccess.h>
#include <asm/arch/hardware.h>				//必须
#include <asm/arch/io.h>				    //包含at91_sys_write()
#include <asm/arch/at91rm9200.h>			//包含各个基地址(必须)
#include <asm/arch/at91rm9200_mc.h>		    //包含EBI_SMC2_CSR[]
#include <asm/arch/at91_pio.h>				//包含GPIO寄存器
#include <asm/arch/at91_pmc.h>				//包含GPIO寄存器
#include <asm/arch/gpio.h>

#undef DPRINTK                               /* undef it, just in case */
#ifdef BEEP_DEBUG
/* This one if debugging is on, and kernel space */
#define DPRINTK(fmt, args...) printk("BEEP: "fmt, ## args)
#else
#define DPRINTK(fmt, args...) /* not debugging: nothing */
#endif


//BEEP引脚
#define		BEEP_PIN        		(AT91_PIN_PD0)                 /* Pc15      */


//定义Beep字符设备结构
typedef struct _beep_dev 
{
    struct cdev chrdev;
}beep_dev,*beep_dev_t;

/* Global variables*/
static int beep_major=0;
static struct class* beep_class;
#define BEEP_NAME	"BEEP0"
//设备指针
static struct platform_device* beep_devices = NULL;
static beep_dev_t at91_beep;

/******   BEEP control cmd   *********/
#define		BEEP_IOCTL_BASE	'B'
#define		BEEP_ON		_IO(BEEP_IOCTL_BASE, 1)	// 响亮
#define		BEEP_OFF  	_IO(BEEP_IOCTL_BASE, 2)	// 静音


//*********************************************************
//BEEP模块打开函数;
//*********************************************************
static int beep_open(struct inode * inode, struct file * filp)
{
	try_module_get(THIS_MODULE);    
	return 0;
}

//*********************************************************
//BEEP模块释放函数;
//*********************************************************
static int beep_release(struct inode * inode,struct file * filp)
{
	module_put(THIS_MODULE);
	return 0;
}

//*********************************************************
//  BEEP I/O 控制函数 ;
//*********************************************************
int beep_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
	switch (cmd) 
	{	
		case BEEP_ON:
			at91_set_gpio_output(BEEP_PIN,1);
			udelay(1);
		break;	 
		
		case BEEP_OFF:
			at91_set_gpio_output(BEEP_PIN,0);
			udelay(1);
		break;	 
		
		default:
			return -EINVAL;
	}
	
	return 0;	 
}

//定义操作函数结构
struct file_operations beep_fops = {
	.owner =    THIS_MODULE,
	.open  =    beep_open,
	.release =  beep_release,
	.ioctl =    beep_ioctl,
};

//系统探测函数
static int __devinit at91beep_probe(struct platform_device *pdev)
{
    int ret;
    dev_t dev_id;
    struct class_device* cls_beep_dev;

    printk("device %s-%d detected!\n", pdev->name, pdev->id);

	at91_set_gpio_output(BEEP_PIN,0);
	at91_sys_write(AT91_PMC_PCER,(0x1 << AT91RM9200_ID_PIOD));	

    at91_beep= kmalloc(sizeof(beep_dev), GFP_KERNEL);

    dev_id = MKDEV(beep_major, 0);
    pdev->dev.devt = dev_id;

    cdev_init(&at91_beep->chrdev, &beep_fops);
    at91_beep->chrdev.owner = THIS_MODULE;

    ret = cdev_add(&at91_beep->chrdev, dev_id, 1);
    if (ret)
    {
        printk("fail to register driver for " BEEP_NAME "%d!\n", pdev->id);
        return ret;
    }

    platform_set_drvdata(pdev, at91_beep);

    cls_beep_dev = class_device_create(beep_class,NULL,dev_id,&pdev->dev,BEEP_NAME);
    if (IS_ERR(cls_beep_dev))
        return PTR_ERR(cls_beep_dev);


    printk("driver for "BEEP_NAME".%d (%d,%d) registered\n", 0, MAJOR(dev_id), MINOR(dev_id));

    return ret;
}


static int __devexit at91beep_remove(struct platform_device *pdev)
{
    beep_dev_t hdev;

    at91_sys_write((AT91_PIOC+PIO_CODR),BEEP_PIN);

    class_device_destroy(beep_class, pdev->dev.devt);

    hdev = platform_get_drvdata(pdev);

    if (hdev)
    {
        cdev_del(&hdev->chrdev);
        kfree(hdev);
    }

    platform_set_drvdata(pdev, NULL);
    pdev->dev.devt = 0;

    printk(BEEP_NAME" removed!\n");

    return 0;
}


#ifdef CONFIG_PM
static int at91beep_suspend(struct platform_device *pdev, pm_message_t state)
{
	return 0;
}

static int at91beep_resume(struct platform_device *pdev)
{
	return 0;
}
#else
#define at91beep_suspend NULL
#define at91beep_resume  NULL
#endif

static struct platform_driver at91beep_driver = 
{   
    .probe      = at91beep_probe,   
    .remove     = __devexit_p(at91beep_remove), 
#ifdef CONFIG_PM    
    .suspend    = at91beep_suspend, 
    .resume     = at91beep_resume,
#endif
    .driver     = 
    {     
        .name   = BEEP_NAME,        
        .owner  = THIS_MODULE,  
    },
};


//*********************************************************
//初始化模块函数;
//*********************************************************
int __init BEEP_at91_init(void)
{	
    int ret;

    dev_t dev = MKDEV(beep_major, 0);

    beep_devices = platform_device_alloc(BEEP_NAME, 0);
    if (!beep_devices)
        return -ENOMEM;

    ret = platform_device_add(beep_devices);
    if (ret < 0) {
        platform_device_put(beep_devices);
        return ret;
    }
		
    /* Figure out our device number. */
    if (beep_major)
        ret = register_chrdev_region(dev, 1, BEEP_NAME);
    else 
    {
        ret = alloc_chrdev_region(&dev, 0, 1, BEEP_NAME);
        if (ret) 
        {
            printk(KERN_WARNING "BEEP_MODULE_NAME: unable to get major %d\n", beep_major);
            return ret;
		}
        beep_major = MAJOR(dev);
    }

    //create class
    beep_class = class_create(THIS_MODULE, BEEP_NAME);
    if (IS_ERR(beep_class))
        return PTR_ERR(beep_class);

    ret = platform_driver_register(&at91beep_driver);

    return ret;

}

//*********************************************************
//注销模块函数;
//*********************************************************
void __exit BEEP_at91_cleanup(void)
{
    platform_driver_unregister(&at91beep_driver);

    class_destroy(beep_class);

    unregister_chrdev_region(MKDEV(beep_major, 0), 1);
    
    platform_device_unregister(beep_devices);

    DPRINTK("unregister driver " BEEP_NAME "\n");
 		  
}

module_init(BEEP_at91_init);
module_exit(BEEP_at91_cleanup);

MODULE_AUTHOR("casiawu");
MODULE_DESCRIPTION("AT91 BEEP Driver ");
MODULE_LICENSE("GPL");
	  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -