蜂鸣器驱动,基于miscdevice子系统。
beepdrv.c
1 /* beepdrv.c 2 TP-6000's beep driver. GUANGZHOU ZHIYUAN 3 4 Copyright (c) 2006 GUANGZHOU ZHIYUAN ELECTRONICS CO.LTD 5 By Chenxibing <Linux@zlgmcu.com> 6 */ 7 8 #include <linux/init.h> 9 #include <linux/module.h> 10 #include <linux/moduleparam.h> 11 #include <linux/kernel.h> 12 #include <linux/fs.h> 13 #include <linux/errno.h> 14 #include <linux/device.h> 15 #include <linux/miscdevice.h> 16 #include <linux/platform_device.h> 17 #include <linux/types.h> 18 #include <linux/io.h> 19 #include <linux/delay.h> 20 #include <linux/irq.h> 21 #include <linux/interrupt.h> 22 23 #include <asm/arch/hardware.h> 24 #include <asm/uaccess.h> 25 #include <asm/arch/irq.h> 26 #include <asm/io.h> 27 #include <asm/pgtable.h> 28 #include <asm/page.h> 29 30 #include <mach/hardware.h> 31 #include <mach/platform.h> 32 33 #include <asm/arch/lpc32xx_gpio.h> 34 35 #include "beepdrv.h" 36 37 #define DEV_NAME "beep" 38 #define GPIO_IOBASE io_p2v(GPIO_BASE) 39 40 static struct semaphore beep_sem; 41 42 static int tp_beep_open(struct inode *inode, struct file *filp) 43 { 44 __raw_writel(_BIT(7), GPIO_P3_OUTP_SET(GPIO_IOBASE));//SET GPIO_07 45 46 try_module_get(THIS_MODULE); 47 printk( KERN_INFO DEV_NAME " opened!\n"); 48 return 0; 49 } 50 51 static int tp_beep_release(struct inode *inode, struct file *filp) 52 { 53 __raw_writel(_BIT(7), GPIO_P3_OUTP_SET(GPIO_IOBASE));//SET GPIO_07 54 55 module_put(THIS_MODULE); 56 printk(KERN_INFO DEV_NAME " released!\n"); 57 return 0; 58 } 59 60 static ssize_t tp_beep_write(struct file *filp, const char __user *buff, size_t count, loff_t *ppos) 61 { 62 int i; 63 unsigned char ctrl=0; 64 65 if (count > 1) { 66 return -EFBIG; 67 } 68 69 if (down_interruptible(&beep_sem)) 70 return -ERESTARTSYS; 71 72 get_user(ctrl, (u8 *)buff); 73 // printk("write date ctrl=0x%0x\n", ctrl); 74 75 76 i = (ctrl-0x30)&0x03; 77 if(i==0) { 78 __raw_writel(_BIT(7), GPIO_P3_OUTP_CLR(GPIO_IOBASE));//CLR GPIO_07 79 80 } else { 81 __raw_writel(_BIT(7), GPIO_P3_OUTP_SET(GPIO_IOBASE));//SET GPIO_07 82 83 } 84 85 up(&beep_sem); 86 return count; 87 } 88 89 static int tp_beep_ioctl(struct inode *inode, struct file *filp, 90 unsigned int cmd, unsigned long arg) 91 { 92 int level; 93 94 if (_IOC_TYPE(cmd) != BEEP_IOC_MAGIC) { 95 return -ENOTTY; 96 } 97 98 if (_IOC_NR(cmd) >= BEEP_IOC_MAXNR) { 99 return -ENOTTY; 100 } 101 102 // printk("arg=0x%x\n", arg); 103 104 105 106 switch (cmd) { 107 case SET_BEEP_ON: 108 //printk("BEEP_ON\n"); 109 110 __raw_writel(_BIT(7), GPIO_P3_OUTP_CLR(GPIO_IOBASE));//CLR GPIO_07 111 112 udelay(10); 113 break; 114 115 case SET_BEEP_OFF: 116 //printk("BEEP_OFF\n"); 117 118 __raw_writel(_BIT(7), GPIO_P3_OUTP_SET(GPIO_IOBASE));//SET GPIO_07 119 120 udelay(10); 121 break; 122 123 default: 124 __raw_writel(_BIT(7), GPIO_P3_OUTP_SET(GPIO_IOBASE));//SET GPIO_07 125 126 break; 127 } 128 129 return 0; 130 } 131 132 static struct file_operations tp_beep_fops = { 133 .owner = THIS_MODULE, 134 .write = tp_beep_write, 135 .ioctl = tp_beep_ioctl, 136 .open = tp_beep_open, 137 .release = tp_beep_release, 138 }; 139 140 static struct miscdevice tp_beep_miscdev = 141 { 142 .minor = MISC_DYNAMIC_MINOR, 143 .name = DEV_NAME, 144 .fops = &tp_beep_fops, 145 }; 146 147 148 static int tp_beep_probe(struct device *dev) 149 { 150 int ret; 151 152 printk(KERN_INFO DEV_NAME " probing...\n"); 153 ret = misc_register(&tp_beep_miscdev); 154 if (ret) 155 printk(KERN_ERR "Failed to register miscdev.\n"); 156 157 return ret; 158 } 159 160 static int tp_beep_remove(struct device *dev) 161 { 162 misc_deregister(&tp_beep_miscdev); 163 printk(KERN_INFO DEV_NAME " removed!\n"); 164 165 return 0; 166 } 167 168 struct platform_device *tp_beep_device; 169 static struct device_driver tp_beep_driver = { 170 .name = DEV_NAME, 171 .owner = THIS_MODULE, 172 .bus = &platform_bus_type, 173 .probe = tp_beep_probe, 174 .remove = tp_beep_remove, 175 }; 176 177 static int __init tp_beep_init(void) 178 { 179 int rc = 0; 180 int i; 181 182 printk(KERN_INFO DEV_NAME " init...\n"); 183 184 for(i=0; i<4; i++) { 185 // s3c2410_beep_cfgpin(BEEP01[i], BEEP01_OUTP[i]); 186 187 // s3c2410_beep_pullup(BEEP01[i], 0); //enable pullup 188 189 // s3c2410_beep_setpin(BEEP01[i], 1); //default all HIGH 190 191 } 192 __raw_writel(_BIT(7), GPIO_P3_OUTP_SET(GPIO_IOBASE));//SET GPIO_07 193 194 195 tp_beep_device = platform_device_register_simple(DEV_NAME, -1, NULL, 0); 196 if(IS_ERR(tp_beep_device)) { 197 goto out; 198 } 199 200 rc = driver_register(&tp_beep_driver); 201 if (rc < 0) { 202 platform_device_unregister(tp_beep_device); 203 } 204 205 sema_init(&beep_sem, 1); 206 out: 207 return rc; 208 } 209 210 static void __exit tp_beep_exit(void) 211 { 212 __raw_writel(_BIT(7), GPIO_P3_OUTP_SET(GPIO_IOBASE));//SET GPIO_07 213 214 printk(KERN_INFO DEV_NAME " init...\n"); 215 driver_unregister(&tp_beep_driver); 216 platform_device_unregister(tp_beep_device); 217 printk(KERN_INFO "tp_beep exit!\n"); 218 } 219 220 module_init(tp_beep_init); 221 module_exit(tp_beep_exit); 222 223 MODULE_AUTHOR("Abing <Linux@zlgmcu.com>"); 224 MODULE_DESCRIPTION("ZHIYUAN tp-beep Driver"); 225 MODULE_LICENSE("GPL");
beepdrv.h
|
|
Makefile
|