0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
| #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/slab.h> #include <linux/uaccess.h> #include <linux/io.h>
#define LED_MAJOR 200 #define LED_NAME "led"
#define CCM_CCGR1_BASE (0x020C406C) #define SW_MUX_GPIO1_IO03_BASE (0x020E0068) #define SW_PAD_GPIO1_IO03_BASE (0x020E02F4) #define GPIO1_DR_BASE (0x0209C000) #define GPIO1_GDIR_BASE (0x0209C004)
static void __iomem *IMX6U_CCM_CCGR1; static void __iomem *SW_MUX_GPIO1_IO03; static void __iomem *SW_PAD_GPIO1_IO03; static void __iomem *GPIO1_DR; static void __iomem *GPIO1_GDIR;
#define LEDOFF 0 #define LEDON 1
void led_switch(u8 sta) { u32 val = 0; if (databuf[0] == LEDOFF) { val = readl(GPIO1_DR); val |= ~(1 << 3); writel(val, GPIO1_DR); } else { val = readl(GPIO1_DR); val &= ~(1 << 3); writel(val, GPIO1_DR); } }
static int led_open(struct inode *inode, struct file *filp) { return 0; }
static int led_release(struct inode *inode, struct file *filp) { return 0; }
static ssize_t led_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos) { int ret; int val = 0; unsigned char databuf[1]; ret = copy_from_user(databuf, buf, count); if (ret < 0){ printk("kernel write fail\n"); return -EFAULT; } led_switch(databuf[0]); return 0; }
static const struct file_operations *fops { .owner = THIS_MODULE, .write = led_write, .open = led_open, .release = led_close, };
static int __init led_init(void) { int ret = 0; int val = 0; printk("led init\n"); IMX6U_CCM_CCGR1 = ioremap(CCM_CCGR1_BASE, 4); SW_MUX_GPIO1_IO03 = ioremap(SW_MUX_GPIO1_IO03_BASE, 4); SW_PAD_GPIO1_IO03 = ioremap(SW_PAD_GPIO1_IO03_BASE, 4); GPIO1_DR = ioremap(GPIO1_DR_BASE, 4); GPIO1_GDIR = ioremap(GPIO1_GDIR_BASE, 4); val = readl(IMX6U_CCM_CCGR1); val &= ~(3 << 26); val |= 3 << 26; writel(val, IMX6U_CCM_CCGR1); writel(0x5, SW_MUX_GPIO1_IO03); writel(0x10B0, SW_PAD_GPIO1_IO03); val = readl(GPIO1_GDIR); val |= 1 << 3; writel(val, GPIO1_GDIR); val = readl(GPIO1_DR); val &= ~(1 << 3); writel(val, GPIO1_DR); ret = register_chrdev(LED_MAJOR, LED_NAME, &fops); if (ret < 0) { printk("chrdev register fail\n"); return -EIO; } }
static void __exit led_exit(void) { int val = 0; val = readl(GPIO1_DR); val |= ~(1 << 3); writel(val, GPIO1_DR); iounmap(IMX6U_CCM_CCGR1); iounmap(SW_MUX_GPIO1_IO03); iounmap(SW_PAD_GPIO1_IO03); iounmap(GPIO1_DR); iounmap(GPIO1_GDIR); unregister_chrdev(LED_MAJOR, LED_NAME); printk("chrdev unregister\n"); }
module_init(led_init); module_exit(led_exit);
MODULE_LICENSE("GPL"); MODULE_AUTHOR("john");
|