Lover雪儿
想念时,就看看天空,无论距离有多远,我们总在同一片天空下!

20150223 IMX257 BEEP驱动程序实现

2015-02-23 李海沿

 

和我们今天上午编写的LED驱动程序一样,此处我们实现一个beep蜂鸣器的鸣叫驱动程序

我们知道我们蜂鸣器的引脚由 GPIO1_26控制的,所以我们此处只需要将前面led驱动程序的相关引脚修改为GPIO1_26 就可以了

(和前面几乎一样,LED驱动程序参考:http://www.cnblogs.com/lihaiyan/p/4297923.html

 

1.确定相关寄存器基址

 

确定IOMUX地址 0x43fa_c000 0x43fa_ffff

 

GPIO1的地址 0x53fc_c000 0x53fc_ffff

MUX_CTL寄存器偏移地址 0x011c

PAD-CTL 寄存器偏移 0x0314

GPIO寄存器偏移地址

 

2.编译测试

 

本驱动程序亲测成功:

附上驱动程序代码:

 

  1 #include<linux/cdev.h>
  2 #include<linux/module.h>
  3 #include<linux/types.h>
  4 #include<linux/fs.h>
  5 #include<linux/errno.h>
  6 #include<linux/mm.h>
  7 #include<linux/sched.h>
  8 #include<linux/init.h>
  9 #include<asm/io.h>
 10 #include<asm/system.h>
 11 #include<asm/uaccess.h>
 12 #include<linux/device.h>
 13 #include <linux/delay.h>
 14 
 15 #define Driver_NAME "beep_dev"
 16 #define DEVICE_NAME "beep_dev"
 17 
 18 static int major = 0;
 19 
 20 //auto to create device node
 21 static struct class *drv_class = NULL;
 22 static struct class_device *drv_class_dev = NULL;
 23 
 24 //beep
 25 //寄存器基址;
 26 static unsigned long mem_iomux;
 27 static unsigned long mem_gpio1;
 28 static unsigned long base_iomux;      //iomux基址 0X 43FA C000 -  0X 43FA FFFF
 29 static unsigned long base_gpio1;    //gpio3      0X 53FC C000 -  0X 53FC FFFF
 30 // MUX_CTL模式选择  配置寄存器
 31 #define MUX_CTL  (*(volatile unsigned long *)(base_iomux + 0x011c))
 32 // PAD_CTL GPIO常用功能设置
 33 #define PAD_CTL  (*(volatile unsigned long *)(base_iomux + 0x0314))
 34 // GPIO DR   数据寄存器  DR
 35 #define DR_GPIO1 (*(volatile unsigned long *)(base_gpio1 + 0x0000))
 36 // GPIO GDIR 方向控制寄存器  GDIR
 37 #define GDIR_GPIO1 (*(volatile unsigned long *)(base_gpio1 + 0x0004))
 38 
 39 
 40 static int key_open(struct inode *inode, struct file *file)
 41 {
 42     printk("<0>function open!\n\n");
 43     return 0;
 44 }
 45 
 46 static int key_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
 47 {
 48     return 0;
 49 }
 50 
 51 static ssize_t key_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
 52 {
 53     printk("<0>function write!\n\n");
 54     return 1;
 55 }
 56 
 57 static int  key_release(struct inode *inode, struct file *filp)
 58 {
 59     printk("<0>function write!\n\n");
 60     return 0;
 61 }
 62 
 63 static int key_ioctl(struct inode *inode,struct file *flip,unsigned int command,unsigned long arg)
 64 {
 65     printk("<0>function ioctl!\n\n");
 66     return 0;
 67 }
 68 static struct file_operations key_fops = {
 69     .owner  =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
 70     .open   =   key_open,
 71     .read   =   key_read,
 72     .write  =   key_write,
 73     .release=   key_release,
 74     .ioctl  =   key_ioctl,
 75 };
 76 
 77 void gpio_addr(void){
 78     printk("<0>addr base_iomux : %x \n",base_iomux);
 79     printk("<0>addr base_gpio1 : %x \n",base_gpio1);
 80     printk("<0>addr MUX_CTL : %x \n",&MUX_CTL);
 81     printk("<0>addr PAD_CTL : %x \n",&PAD_CTL);
 82     printk("<0>addr GDIR_GPIO1 : %x \n",&GDIR_GPIO1);
 83     printk("<0>addr DR_GPIO1 : %x \n",&DR_GPIO1);
 84 }
 85 
 86 void beep_on_off(void){
 87     ssleep(1);
 88     DR_GPIO1 |= (0x01 << 26);        //将GPIO1_26置1
 89     ssleep(1);
 90     DR_GPIO1 &= ~(0x01 << 26);        //将GPIO1_26清零
 91     ssleep(1);
 92     DR_GPIO1 |= (0x01 << 26);        //将GPIO1_26置1
 93     ssleep(1);
 94     DR_GPIO1 &= ~(0x01 << 26);        //将GPIO1_26清零
 95     ssleep(1);
 96     DR_GPIO1 |= (0x01 << 26);        //将GPIO1_26置1
 97     ssleep(1);
 98     DR_GPIO1 &= ~(0x01 << 26);        //将GPIO1_26清零
 99     ssleep(1);
100     DR_GPIO1 |= (0x01 << 26);        //将GPIO1_26置1
101     ssleep(1);
102     DR_GPIO1 &= ~(0x01 << 26);        //将GPIO1_26清零
103     ssleep(1);
104     DR_GPIO1 |= (0x01 << 26);        //将GPIO1_26置1
105     ssleep(1);
106     DR_GPIO1 &= ~(0x01 << 26);        //将GPIO1_26清零
107 }
108 
109 static int __init  key_irq_init(void)
110 {
111     printk("<0>\nHello,this is %s module!\n\n",Driver_NAME);
112     //register and mknod
113     major = register_chrdev(0,Driver_NAME,&key_fops);
114     drv_class = class_create(THIS_MODULE,Driver_NAME);
115     drv_class_dev = device_create(drv_class,NULL,MKDEV(major,0),NULL,DEVICE_NAME);  /*/dev/key_query*/
116     
117     //IO端口申请 ioremap  可以直接通过指针来访问这些地址
118     base_iomux = ioremap(0x43FAC000,0xFFF);
119     base_gpio1 = ioremap(0x53FCC000,0xFFF);
120 
121     //MUX_CTL
122     MUX_CTL &= ~(0x07 << 0);    
123     MUX_CTL |= (0X05 << 0);    //设置为ALT5  GPIO1_26 BEEP
124     //PAD_CTL
125     PAD_CTL &= ~(0x01<<13 | 0x01<<3 | 0x03<<1 | 0x01<<0);   //1.8v 不需要上拉下拉  CMOS输出 slew rate
126     //GDIR_GPIO1    配置为输出模式
127     GDIR_GPIO1 &= ~(0x01 << 26);    
128     GDIR_GPIO1 |= (0x01 << 26);    //配置为输出模式    
129 
130     //DR_GPIO1        配置为输出0 点亮ERR_LED
131     DR_GPIO1 &= ~(0x01 << 26);        //将GPIO1_26清零
132     DR_GPIO1 &= ~(0x01 << 26);        //将GPIO1_26清零
133     gpio_addr();
134     beep_on_off();
135     return 0; 
136 }
137                      
138 static void __exit key_irq_exit(void)
139 {
140     gpio_addr();
141     printk("<0>\nGoodbye,%s!\n\n",Driver_NAME);
142     beep_on_off();
143 
144        unregister_chrdev(major,Driver_NAME);
145     device_unregister(drv_class_dev);
146     class_destroy(drv_class);
147     
148     //释放IO端口
149     iounmap(base_iomux);
150     iounmap(base_gpio1);
151 }
152 
153 
154 /* 这两行指定驱动程序的初始化函数和卸载函数 */
155 module_init(key_irq_init);
156 module_exit(key_irq_exit);
157 
158 /* 描述驱动程序的一些信息,不是必须的 */
159 MODULE_AUTHOR("Lover雪儿");
160 MODULE_VERSION("0.1.0");
161 MODULE_DESCRIPTION("IMX257 key Driver");
162 MODULE_LICENSE("GPL");
View Code

 

posted on 2015-02-23 16:09  Lover雪儿  阅读(382)  评论(0编辑  收藏  举报