1.确定相关寄存器基址
确定IOMUX地址 0x43fa_c000 0x43fa_ffff
GPIO1的地址 0x53fc_c000 0x53fc_ffff
MUX_CTL寄存器偏移地址 0x011c
PAD-CTL 寄存器偏移 0x0314
GPIO寄存器偏移地址
2.编译测试
本驱动程序亲测成功:
附上驱动程序代码:
1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
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!nn');
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!nn');
54 return 1;
55 }
56
57 static int key_release(struct inode *inode, struct file *filp)
58 {
59 printk('<0>function write!nn');
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!nn');
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!nn',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!nn',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');