//led_misc.c
1 #include <linux/miscdevice.h>
2 #include <linux/delay.h>
3 #include <asm/irq.h>
4 #include <mach/regs-gpio.h>
5 #include <mach/hardware.h>
6 #include <linux/kernel.h>
7 #include <linux/module.h>
8 #include <linux/init.h>
9 #include <linux/mm.h>
10 #include <linux/fs.h>
11 #include <linux/types.h>
12 #include <linux/delay.h>
13 #include <linux/moduleparam.h>
14 #include <linux/slab.h>
15 #include <linux/errno.h>
16 #include <linux/ioctl.h>
17 #include <linux/cdev.h>
18 #include <linux/string.h>
19 #include <linux/list.h>
20 #include <linux/pci.h>
21 #include <asm/uaccess.h>
22 #include <asm/atomic.h>
23 #include <asm/unistd.h>
24 #include <mach/map.h>
25 #include <mach/regs-clock.h>
26 #include <mach/regs-gpio.h>
27 #include <plat/gpio-cfg.h>
28 #include <mach/gpio-bank-e.h>
29 #include <mach/gpio-bank-k.h>
30
31 #define DEVICE_NAME "leds_by_hui"
32
33 static long sbc2440_leds_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
34 {
35 unsigned long tmp;
36 switch(cmd) {
37 case 0: /*led off*/
38 tmp = readl(S3C64XX_GPKDAT); //从内存映射的i/o空间读取32位数据
39 tmp |= (0x1<<8);
40 writel(tmp, S3C64XX_GPKDAT); //向i/o地址写入32位数据
41 printk("<0>led off\n");
42 break;
43 case 1: /*led on*/
44 tmp = readl(S3C64XX_GPKDAT);
45 tmp &= ~(0x1<<8);
46 writel(tmp, S3C64XX_GPKDAT);
47 printk("<0>led on\n");
48 break;
49 }
50 return 0;
51 }
52
53 static struct file_operations dev_fops = {
54 .owner = THIS_MODULE,
55 .unlocked_ioctl = sbc2440_leds_ioctl,
56 };
57
58
59 static struct miscdevice misc = {
60 .minor = MISC_DYNAMIC_MINOR,
61 .name = DEVICE_NAME,
62 .fops = &dev_fops,
63 };
64
65 static int __init dev_init(void)
66 {
67 int ret;
68
69 unsigned long tmp;
70 tmp = readl(S3C64XX_GPKCON1);
71 tmp &= ~(0xe<<0); /*0001 output*/
72 tmp |= (0x1<<0);
73 writel(tmp, S3C64XX_GPKCON1); //初始化控制寄存器
74
75 tmp = readl(S3C64XX_GPKPUD);
76 tmp &= ~(0x3<<8); /*disable pull-up/down*/
77 writel(tmp, S3C64XX_GPKPUD); //初始化数据寄存器
78
79 tmp = readl(S3C64XX_GPKDAT);
80 tmp &= ~(0x1<<8); /*low */
81 writel(tmp, S3C64XX_GPKDAT); //初始化数据寄存器
82
83 ret = misc_register(&misc); //注册主设备号为10的特殊字符设备
84
85 printk(DEVICE_NAME"\tinitialized\n");
86 printk("<0>init led on \n");
87
88 return ret;
89
90 }
91
92 static void __exit dev_exit(void)
93 {
94 unsigned long tmp;
95 tmp = readl(S3C64XX_GPKDAT); /*led off*/
96 tmp |= (0x1<<8); /*hight */
97 writel(tmp, S3C64XX_GPKDAT); //初始化数据寄存器
98
99 printk("<0> led off\n");
100
101 misc_deregister(&misc);
102 }
103
104 module_init(dev_init);
105 module_exit(dev_exit);
106 MODULE_LICENSE("GPL");
107 MODULE_AUTHOR("FriendlyARM Inc.");
测试程序:
//led_misc_test.c
1 #include<unistd.h>
2 #include<stdio.h>
3 #include<stdlib.h>
4 #include<sys/ioctl.h>
5
6 int main(int argc, char **argv)
7 {
8 int fd;
9 unsigned int state;
10
11 if(argc != 2 || sscanf(argv[1],"%d",&state) != 1 || state > 1 ){
12 printf("Useage: xxx #./filename 1|0 \n");
13 exit(0);
14 }
15
16 fd = open("/dev/leds_by_hui",0);
17 if(fd < 0){
18 printf("error to open /dev/led_by_hui\n");
19 exit(0);
20 }
21
22 ioctl(fd,state,NULL);
23 close(fd);
24 return 0;
25 }
