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 #include
15
16 static volatile unsigned long *ledcon;
17 static volatile unsigned long *leddat;
18 static struct class *led_class;
19 static unsigned int pin_th;
20 dev_t led_dev;
21 struct cdev *cdev;
22
23
24 /* 打开led灯 */
25 static int led_open(struct inode *inode, struct file *file)
26 {
27 *ledcon &= ~(0x3 << (pin_th * 2));
28 *ledcon |= (0x1 << (pin_th * 2));
29 *leddat &= ~(1 << pin_th);
30 return 0;
31 }
32
33 static struct file_operations led_fops = {
34 .owner = THIS_MODULE,
35 .open = led_open,
36 };
37
38 static int led_probe(struct platform_device *pdev)
39 {
40 int pin_info;
41 int phy_addr;
42 int io_base;
43 of_property_read_s32(pdev->dev.of_node, "pin", &pin_info);
44 printk("pin_info = 0x%xn", pin_info);
45 of_property_read_s32(pdev->dev.of_node, "iobase", &io_base);
46 printk("io_base = 0x%xn", io_base);
47 pin_th = pin_info & (0xffff);
48 phy_addr = (io_base | ((pin_info>>16)<<4));
49 ledcon = ioremap(phy_addr, 2);
50 leddat = ledcon + 1;
51
52 if (alloc_chrdev_region(&led_dev, MINOR(led_dev), 1, "led"))
53 return -1;
54 cdev = cdev_alloc();
55 if (!cdev)
56 return -1;
57 cdev_init(cdev, &led_fops);
58 cdev_add(cdev, led_dev, 1);
59
60 led_class = class_create(THIS_MODULE, "led");
61 device_create(led_class,NULL,led_dev,NULL,"led0"); // is /dev/led0
62
63 return 0;
64
65 }
66
67 int led_remove(struct platform_device *pdev)
68 {
69 device_destroy(led_class, led_dev);
70 class_destroy(led_class);
71 cdev_del(cdev);
72 unregister_chrdev_region(led_dev, 1);
73 iounmap(ledcon);
74 return 0;
75 }
76
77 static struct of_device_id led_id[] = {
78 {.compatible = "jz2440_led"},
79 {},
80 };
81
82 static struct platform_driver led_drv = {
83 .probe = led_probe,
84 .remove = led_remove,
85 .driver = {
86 .name = "jz2440_led",
87 .of_match_table = led_id,
88 },
89 };
90
91 static int led_init(void)
92 {
93 platform_driver_register(&led_drv);
94 return 0;
95 }
96
97 static void led_exit(void)
98 {
99 platform_driver_unregister(&led_drv);
100 }
101
102 module_init(led_init);
103 module_exit(led_exit);
104
105 MODULE_LICENSE("GPL");
以上是驱动程序,下面是设备树dts文件:
1 #define S3C2440_GPA(_nr) ((0<<16) + (_nr))
2 #define S3C2440_GPB(_nr) ((1<<16) + (_nr))
3 #define S3C2440_GPC(_nr) ((2<<16) + (_nr))
4 #define S3C2440_GPD(_nr) ((3<<16) + (_nr))
5 #define S3C2440_GPE(_nr) ((4<<16) + (_nr))
6 #define S3C2440_GPF(_nr) ((5<<16) + (_nr))
7 #define S3C2440_GPG(_nr) ((6<<16) + (_nr))
8 #define S3C2440_GPH(_nr) ((7<<16) + (_nr))
9 #define S3C2440_GPJ(_nr) ((8<<16) + (_nr))
10 #define S3C2440_GPK(_nr) ((9<<16) + (_nr))
11 #define S3C2440_GPL(_nr) ((10<<16) + (_nr))
12 #define S3C2440_GPM(_nr) ((11<<16) + (_nr))
13
14 /dts-v1/;
15
16 / {
17 model = "SMDK2440";
18 compatible = "samsung,smdk2440";
19
20 #address-cells = <1>;
21 #size-cells = <1>;
22
23 memory@30000000 {
24 device_type = "memory";
25 reg = <0x30000000 0x4000000>;
26 };
34 chosen {
35 bootargs = "noinitrd root=/dev/mtdblock4 rw init=/linuxrc console=ttySAC0,115200";
36 };
37
38
39 led {
40 compatible = "jz2440_led";
41 pin =
42 iobase = <0x56000000>;
43 };
44 };