总线设备驱动模型法

led_dev.c

 1 #include <linux/module.h>
 2 #include <linux/version.h>
 3 
 4 #include <linux/init.h>
 5 
 6 #include <linux/kernel.h>
 7 #include <linux/types.h>
 8 #include <linux/interrupt.h>
 9 #include <linux/list.h>
10 #include <linux/timer.h>
11 #include <linux/init.h>
12 #include <linux/serial_core.h>
13 #include <linux/platform_device.h>
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 <linux/module.h>
  2 #include <linux/kernel.h>
  3 #include <linux/fs.h>
  4 #include <linux/init.h>
  5 #include <linux/delay.h>
  6 #include <linux/uaccess.h>
  7 #include <asm/irq.h>
  8 #include <asm/io.h>
  9 #include <linux/of.h>
 10 #include <linux/of_device.h>
 11 #include <linux/of_platform.h>
 12 #include <linux/platform_device.h>
 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%x\n", 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<<pin);
 86     }
 87     else
 88     {
 89         /* 灭灯 */
 90         *gpio_dat |= (1<<pin);
 91     }
 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 <sys/types.h>
 2 #include <sys/stat.h>
 3 #include <fcntl.h>
 4 #include <stdio.h>
 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 <on|off>\n", argv[0]);
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 }

猜你喜欢

转载自www.cnblogs.com/-glb/p/11210512.html