led_dev.c
1 #include
2 #include
3
4 #include
5
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
14
15 #define S3C2440_GPA(n) (0<<16 | n)
16 #define S3C2440_GPB(n) (1<<16 | n)
17 #define S3C2440_GPC(n) (2<<16 | n)
18 #define S3C2440_GPD(n) (3<<16 | n)
19 #define S3C2440_GPE(n) (4<<16 | n)
20 #define S3C2440_GPF(n) (5<<16 | n)
21 #define S3C2440_GPG(n) (6<<16 | n)
22 #define S3C2440_GPH(n) (7<<16 | n)
23 #define S3C2440_GPI(n) (8<<16 | n)
24 #define S3C2440_GPJ(n) (9<<16 | n)
25
26
27 /* 分配/设置/注册一个platform_device */
28
29 static struct resource led_resource[] = {
30 [0] = {
31 .start = S3C2440_GPF(5),
32 .end = S3C2440_GPF(5),
33 .flags = IORESOURCE_MEM,
34 },
35 };
36
37 static void led_release(struct device * dev)
38 {
39 }
40
41
42 static struct platform_device led_dev = {
43 .name = "myled",
44 .id = -1,
45 .num_resources = ARRAY_SIZE(led_resource),
46 .resource = led_resource,
47 .dev = {
48 .release = led_release,
49 },
50 };
51
52 static int led_dev_init(void)
53 {
54 platform_device_register(&led_dev);
55 return 0;
56 }
57
58 static void led_dev_exit(void)
59 {
60 platform_device_unregister(&led_dev);
61 }
62
63 module_init(led_dev_init);
64 module_exit(led_dev_exit);
65
66 MODULE_LICENSE("GPL");
led_drv.c
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
14 #define S3C2440_GPA(n) (0<<16 | n)
15 #define S3C2440_GPB(n) (1<<16 | n)
16 #define S3C2440_GPC(n) (2<<16 | n)
17 #define S3C2440_GPD(n) (3<<16 | n)
18 #define S3C2440_GPE(n) (4<<16 | n)
19 #define S3C2440_GPF(n) (5<<16 | n)
20 #define S3C2440_GPG(n) (6<<16 | n)
21 #define S3C2440_GPH(n) (7<<16 | n)
22 #define S3C2440_GPI(n) (8<<16 | n)
23 #define S3C2440_GPJ(n) (9<<16 | n)
24
25 static int led_pin;
26 static volatile unsigned int *gpio_con;
27 static volatile unsigned int *gpio_dat;
28
29 /* 123. 分配/设置/注册file_operations
30 * 4. 入口
31 * 5. 出口
32 */
33
34 static int major;
35 static struct class *led_class;
36
37 static unsigned int gpio_base[] = {
38 0x56000000, /* GPACON */
39 0x56000010, /* GPBCON */
40 0x56000020, /* GPCCON */
41 0x56000030, /* GPDCON */
42 0x56000040, /* GPECON */
43 0x56000050, /* GPFCON */
44 0x56000060, /* GPGCON */
45 0x56000070, /* GPHCON */
46 0, /* GPICON */
47 0x560000D0, /* GPJCON */
48 };
49
50 static int led_open (struct inode *node, struct file *filp)
51 {
52 /* 把LED引脚配置为输出引脚 */
53 /* GPF5 - 0x56000050 */
54 int bank = led_pin >> 16;
55 int base = gpio_base[bank];
56
57 int pin = led_pin & 0xffff;
58 gpio_con = ioremap(base, 8);
59 if (gpio_con) {
60 printk("ioremap(0x%x) = 0x%xn", base, gpio_con);
61 }
62 else {
63 return -EINVAL;
64 }
65
66 gpio_dat = gpio_con + 1;
67
68 *gpio_con &= ~(3<<(pin * 2));
69 *gpio_con |= (1<<(pin * 2));
70
71 return 0;
72 }
73
74 static ssize_t led_write (struct file *filp, const char __user *buf, size_t size, loff_t *off)
75 {
76 /* 根据APP传入的值来设置LED引脚 */
77 unsigned char val;
78 int pin = led_pin & 0xffff;
79
80 copy_from_user(&val, buf, 1);
81
82 if (val)
83 {
84 /* 点灯 */
85 *gpio_dat &= ~(1<
87 else
88 {
89 /* 灭灯 */
90 *gpio_dat |= (1<
92
93 return 1; /* 已写入1个数据 */
94 }
95
96 static int led_release (struct inode *node, struct file *filp)
97 {
98 printk("iounmap(0x%x)n", gpio_con);
99 iounmap(gpio_con);
100 return 0;
101 }
102
103
104 static struct file_operations myled_oprs = {
105 .owner = THIS_MODULE,
106 .open = led_open,
107 .write = led_write,
108 .release = led_release,
109 };
110
111
112 static int led_probe(struct platform_device *pdev)
113 {
114 struct resource *res;
115
116 /* 根据platform_device的资源进行ioremap */
117 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
118 led_pin = res->start;
119
120 major = register_chrdev(0, "myled", &myled_oprs);
121
122 led_class = class_create(THIS_MODULE, "myled");
123 device_create(led_class, NULL, MKDEV(major, 0), NULL, "led"); /* /dev/led */
124
125 return 0;
126 }
127
128 static int led_remove(struct platform_device *pdev)
129 {
130 unregister_chrdev(major, "myled");
131 device_destroy(led_class, MKDEV(major, 0));
132 class_destroy(led_class);
133
134 return 0;
135 }
136
137
138 struct platform_driver led_drv = {
139 .probe = led_probe,
140 .remove = led_remove,
141 .driver = {
142 .name = "myled",
143 }
144 };
145
146
147 static int myled_init(void)
148 {
149 platform_driver_register(&led_drv);
150 return 0;
151 }
152
153 static void myled_exit(void)
154 {
155 platform_driver_unregister(&led_drv);
156 }
157
158
159
160 module_init(myled_init);
161 module_exit(myled_exit);
162
163
164 MODULE_LICENSE("GPL");
2、测试程序
1 #include
2 #include
3 #include
4 #include
5
6 /* ledtest on
7 * ledtest off
8 */
9 int main(int argc, char **argv)
10 {
11 int fd;
12 unsigned char val = 1;
13 fd = open("/dev/led", O_RDWR);
14 if (fd < 0)
15 {
16 printf("can't open!n");
17 }
18 if (argc != 2)
19 {
20 printf("Usage :n");
21 printf("%s
22 return 0;
23 }
24
25 if (strcmp(argv[1], "on") == 0)
26 {
27 val = 1;
28 }
29 else
30 {
31 val = 0;
32 }
33
34 write(fd, &val, 1);
35 return 0;
36 }