免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1026 | 回复: 0
打印 上一主题 下一主题

Beep Driver [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-10-14 20:29 |只看该作者 |倒序浏览
Beep Driver
蜂鸣器驱动,基于miscdevice子系统。
beepdrv.c/* beepdrv.c
   TP-6000's beep driver. GUANGZHOU ZHIYUAN
   Copyright (c) 2006 GUANGZHOU ZHIYUAN ELECTRONICS CO.LTD
   By Chenxibing   
*/
#include linux/init.h>
#include linux/module.h>
#include linux/moduleparam.h>
#include linux/kernel.h>
#include linux/fs.h>
#include linux/errno.h>
#include linux/device.h>
#include linux/miscdevice.h>
#include linux/platform_device.h>
#include linux/types.h>
#include linux/io.h>
#include linux/delay.h>
#include linux/irq.h>
#include linux/interrupt.h>
#include asm/arch/hardware.h>
#include asm/uaccess.h>
#include asm/arch/irq.h>
#include asm/io.h>
#include asm/pgtable.h>
#include asm/page.h>
#include mach/hardware.h>
#include mach/platform.h>
#include asm/arch/lpc32xx_gpio.h>
#include "beepdrv.h"
#define DEV_NAME    "beep"
#define GPIO_IOBASE io_p2v(GPIO_BASE)
static struct semaphore beep_sem;
static int tp_beep_open(struct inode *inode, struct file *filp)
{
        __raw_writel(_BIT(7), GPIO_P3_OUTP_SET(GPIO_IOBASE));//SET GPIO_07
    try_module_get(THIS_MODULE);
    printk( KERN_INFO DEV_NAME " opened!\n");
    return 0;
}
static int tp_beep_release(struct inode *inode, struct file *filp)
{
        __raw_writel(_BIT(7), GPIO_P3_OUTP_SET(GPIO_IOBASE));//SET GPIO_07
    module_put(THIS_MODULE);
    printk(KERN_INFO DEV_NAME " released!\n");
    return 0;
}
static ssize_t tp_beep_write(struct file *filp, const char __user *buff, size_t count, loff_t *ppos)
{
    int i;
    unsigned char ctrl=0;
   
    if (count > 1) {
        return -EFBIG;
    }
   
    if (down_interruptible(&beep_sem))
        return -ERESTARTSYS;
    get_user(ctrl, (u8 *)buff);
//    printk("write date ctrl=0x%0x\n", ctrl);
    i = (ctrl-0x30)&0x03;
    if(i==0) {
        __raw_writel(_BIT(7), GPIO_P3_OUTP_CLR(GPIO_IOBASE));//CLR GPIO_07
    } else {
        __raw_writel(_BIT(7), GPIO_P3_OUTP_SET(GPIO_IOBASE));//SET GPIO_07
    }
    up(&beep_sem);
    return count;
}
static int tp_beep_ioctl(struct inode *inode, struct file *filp,
                        unsigned int cmd, unsigned long arg)
{
     int level;
    if (_IOC_TYPE(cmd) != BEEP_IOC_MAGIC) {
        return -ENOTTY;
    }
    if (_IOC_NR(cmd) >= BEEP_IOC_MAXNR) {
        return -ENOTTY;
    }
//    printk("arg=0x%x\n", arg);
    switch (cmd) {
    case SET_BEEP_ON:
        //printk("BEEP_ON\n");
        __raw_writel(_BIT(7), GPIO_P3_OUTP_CLR(GPIO_IOBASE));//CLR GPIO_07
        udelay(10);
        break;
        
    case SET_BEEP_OFF:
        //printk("BEEP_OFF\n");
        __raw_writel(_BIT(7), GPIO_P3_OUTP_SET(GPIO_IOBASE));//SET GPIO_07
        udelay(10);
        break;
    default:
        __raw_writel(_BIT(7), GPIO_P3_OUTP_SET(GPIO_IOBASE));//SET GPIO_07
        break;
    }
    return 0;
}
static struct file_operations tp_beep_fops = {
    .owner   = THIS_MODULE,
    .write   = tp_beep_write,
    .ioctl     = tp_beep_ioctl,
    .open    = tp_beep_open,
    .release = tp_beep_release,
};
static struct miscdevice tp_beep_miscdev =
{
     .minor    = MISC_DYNAMIC_MINOR,
     .name    = DEV_NAME,
     .fops    = &tp_beep_fops,
};
static int tp_beep_probe(struct device *dev)
{
    int ret;
    printk(KERN_INFO DEV_NAME " probing...\n");
    ret = misc_register(&tp_beep_miscdev);
    if (ret)
        printk(KERN_ERR "Failed to register miscdev.\n");
    return ret;
}
static int tp_beep_remove(struct device *dev)
{
    misc_deregister(&tp_beep_miscdev);
    printk(KERN_INFO DEV_NAME " removed!\n");
   
    return 0;
}
struct platform_device *tp_beep_device;
static struct device_driver tp_beep_driver = {
        .name    = DEV_NAME,
        .owner   = THIS_MODULE,
        .bus     = &platform_bus_type,
        .probe   = tp_beep_probe,
        .remove  = tp_beep_remove,
};
static int __init tp_beep_init(void)
{
    int rc = 0;
    int i;
    printk(KERN_INFO DEV_NAME " init...\n");
    for(i=0; i4; i++) {
    //        s3c2410_beep_cfgpin(BEEP01, BEEP01_OUTP);
    //    s3c2410_beep_pullup(BEEP01,  0); //enable pullup
    //        s3c2410_beep_setpin(BEEP01,  1); //default all HIGH
    }
        __raw_writel(_BIT(7), GPIO_P3_OUTP_SET(GPIO_IOBASE));//SET GPIO_07
    tp_beep_device = platform_device_register_simple(DEV_NAME, -1, NULL, 0);
    if(IS_ERR(tp_beep_device)) {
        goto out;
    }
        
    rc = driver_register(&tp_beep_driver);
        if (rc  0) {
            platform_device_unregister(tp_beep_device);
    }
    sema_init(&beep_sem, 1);
out:
        return rc;   
}
static void __exit tp_beep_exit(void)
{
        __raw_writel(_BIT(7), GPIO_P3_OUTP_SET(GPIO_IOBASE));//SET GPIO_07
    printk(KERN_INFO DEV_NAME " init...\n");
    driver_unregister(&tp_beep_driver);
    platform_device_unregister(tp_beep_device);
    printk(KERN_INFO "tp_beep exit!\n");
}
module_init(tp_beep_init);
module_exit(tp_beep_exit);
MODULE_AUTHOR("Abing ");
MODULE_DESCRIPTION("ZHIYUAN tp-beep Driver");
MODULE_LICENSE("GPL");
beepdrv.h
#ifndef __BEEPDRV_H#define __BEEPDRV_H#include linux/ioctl.h>#define BEEP_IOC_MAGIC     'b'#define SET_BEEP_ON     _IO(BEEP_IOC_MAGIC, 0)#define SET_BEEP_OFF    _IO(BEEP_IOC_MAGIC, 1)#define BEEP_IOC_MAXNR    2#endif //__BEEPDRV_H[color="#000000"]

Makefile
# Makefile2.6
ifneq ($(KERNELRELEASE),)
#kbuild syntax. dependency relationshsip of files and target modules are listed here.
obj-m := beepdrv.o
else
PWD  := $(shell pwd)
KVER = 2.6.27.8
KDIR := /home/chenxibing/lpc3250/linux-2.6.27.8/
all:
    $(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
    rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions
endif


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/51797/showart_2070484.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP