📄 beep.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 + -