1 /* MOXART GPIO (LEDs and RESET pin) driver (based on MOXA sources)
2 * Copyright (C) 2013 Jonas Jensen <jonas.jensen@gmail.com>
3 * This program is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License as published by the
5 * Free Software Foundation; either version 2 of the License,
6 * or (at your option) any later version. */
8 #include <linux/kernel.h>
9 #include <linux/init.h>
11 #include <linux/irq.h>
12 #include <linux/gpio.h>
13 #include <linux/delay.h>
14 #include <linux/module.h>
15 #include <linux/types.h>
16 #include <linux/miscdevice.h>
17 #include <linux/fcntl.h>
18 #include <linux/poll.h>
19 #include <linux/proc_fs.h>
20 #include <linux/spinlock.h>
21 #include <linux/rtc.h>
22 #include <linux/timer.h>
23 #include <linux/ioport.h>
24 #include <linux/kmod.h>
27 #include <asm/uaccess.h>
28 #include <asm/system.h>
30 #include <mach/hardware.h>
31 #include <mach/irqs.h>
32 #include <mach/gpio.h>
34 #define MOXA_MISC_MINOR 105
35 #define RESET_POLL_TIME (HZ/5)
36 #define RESET_TIMEOUT (HZ * 5)
37 #define IOCTL_SW_READY_ON 1
38 #define IOCTL_SW_READY_OFF 2
40 static struct timer_list reset_timer
;
42 static DEFINE_SPINLOCK(reset_lock
);
43 static DEFINE_SPINLOCK(gpio_lock
);
45 static unsigned long reset_time_end
, reset_time_interval
;
46 static int led_on_off_flag
;
47 static struct work_struct reset_pin_detected_queue
;
49 void moxart_gpio_mp_set(u32 gpio
)
53 spin_lock_irqsave(&gpio_lock
, flags
);
54 writel(readl(IO_ADDRESS(MOXART_PMU_BASE
)+0x100) |
55 gpio
, IO_ADDRESS(MOXART_PMU_BASE
)+0x100);
56 spin_unlock_irqrestore(&gpio_lock
, flags
);
59 void moxart_gpio_mp_clear(u32 gpio
)
63 spin_lock_irqsave(&gpio_lock
, flags
);
64 writel(readl(IO_ADDRESS(MOXART_PMU_BASE
)+0x100) &
65 ~gpio
, IO_ADDRESS(MOXART_PMU_BASE
)+0x100);
66 spin_unlock_irqrestore(&gpio_lock
, flags
);
69 void moxart_gpio_inout(u32 gpio
, bool inout
)
72 void __iomem
*ioaddr
= (void __force __iomem
*)
73 GPIO_PIN_DIRECTION(IO_ADDRESS(MOXART_GPIO_BASE
));
75 spin_lock_irqsave(&gpio_lock
, flags
);
76 (inout
) ? writel(readl(ioaddr
) | gpio
, ioaddr
) :
77 writel(readl(ioaddr
) & ~gpio
, ioaddr
);
78 spin_unlock_irqrestore(&gpio_lock
, flags
);
81 void moxart_gpio_set(u32 gpio
, bool highlow
)
84 void __iomem
*ioaddr
= (void __force __iomem
*)
85 GPIO_DATA_OUT(IO_ADDRESS(MOXART_GPIO_BASE
));
87 spin_lock_irqsave(&gpio_lock
, flags
);
88 (highlow
) ? writel(readl(ioaddr
) | gpio
, ioaddr
) :
89 writel(readl(ioaddr
) & ~gpio
, ioaddr
);
90 spin_unlock_irqrestore(&gpio_lock
, flags
);
93 u32
moxart_gpio_get(u32 gpio
)
98 spin_lock_irqsave(&gpio_lock
, flags
);
99 ret
= readl(GPIO_PIN_DIRECTION(IO_ADDRESS(MOXART_GPIO_BASE
)));
101 /* printk(KERN_INFO "MOXART GPIO: moxart_gpio_get: readl(%x)"
102 "=%x\n", GPIO_DATA_OUT(IO_ADDRESS(MOXART_GPIO_BASE)),
103 readl(GPIO_DATA_OUT(IO_ADDRESS(MOXART_GPIO_BASE))));*/
104 ret
= readl(GPIO_DATA_OUT(IO_ADDRESS(MOXART_GPIO_BASE
))) & gpio
;
106 ret
= readl(GPIO_DATA_IN(IO_ADDRESS(MOXART_GPIO_BASE
))) & gpio
;
108 spin_unlock_irqrestore(&gpio_lock
, flags
);
112 void moxart_gpio_write_byte(u8 data
)
115 for (i
= 0; i
< 8; i
++, data
>>= 1) {
116 moxart_gpio_set(GPIO_RTC_SCLK
, GPIO_EM1240_LOW
);
117 moxart_gpio_set(GPIO_RTC_DATA
, ((data
& 1) == 1));
118 udelay(GPIO_RTC_DELAY_TIME
);
119 moxart_gpio_set(GPIO_RTC_SCLK
, GPIO_EM1240_HIGH
);
120 udelay(GPIO_RTC_DELAY_TIME
);
124 u8
moxart_gpio_read_byte(void)
128 for (i
= 0; i
< 8; i
++) {
129 moxart_gpio_set(GPIO_RTC_SCLK
, GPIO_EM1240_LOW
);
130 udelay(GPIO_RTC_DELAY_TIME
);
131 moxart_gpio_set(GPIO_RTC_SCLK
, GPIO_EM1240_HIGH
);
132 if (moxart_gpio_get(GPIO_RTC_DATA
))
134 udelay(GPIO_RTC_DELAY_TIME
);
139 void reset_pin_detected(struct work_struct
*work
)
141 /* char *argv[2], *envp[5]; */
145 pr_info("MOXART GPIO: reset_pin_detected\n");
147 /* commenting below, not everyone is going to
148 * have /bin/setdef binary.. */
150 /*if (!current->fs->root) return;
151 argv[0] = "/bin/setdef";
154 envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
156 call_usermodehelper(argv[0], argv, envp, 0);
160 void reset_poll(unsigned long ingore
)
164 spin_lock_irqsave(&reset_lock
, flags
);
165 del_timer(&reset_timer
);
167 /* printk(KERN_INFO "MOXART GPIO: reset_poll: moxart_gpio_get"
168 * "(SW_READY_GPIO) = %x\n", moxart_gpio_get(SW_READY_GPIO)); */
169 moxart_gpio_get(SW_READY_GPIO
);
170 if (!moxart_gpio_get(SW_RESET_GPIO
)) {
171 if (reset_time_end
== 0) {
172 reset_time_end
= jiffies
+ RESET_TIMEOUT
;
173 reset_time_interval
= jiffies
+ HZ
;
174 } else if (time_after(jiffies
, reset_time_end
)) {
175 moxart_gpio_set(SW_READY_GPIO
, GPIO_EM1240_HIGH
);
176 schedule_work(&reset_pin_detected_queue
);
178 } else if (time_after(jiffies
, reset_time_interval
)) {
179 if (led_on_off_flag
) {
181 moxart_gpio_set(SW_READY_GPIO
,
185 moxart_gpio_set(SW_READY_GPIO
,
188 reset_time_interval
= jiffies
+ HZ
;
190 } else if (reset_time_end
) {
193 moxart_gpio_set(SW_READY_GPIO
, GPIO_EM1240_LOW
);
195 reset_timer
.function
= reset_poll
;
196 reset_timer
.expires
= jiffies
+ RESET_POLL_TIME
;
197 add_timer(&reset_timer
);
200 spin_unlock_irqrestore(&reset_lock
, flags
);
203 static int gpio_ioctl(struct inode
*inode
, struct file
*file
,
204 unsigned int cmd
, unsigned long arg
)
207 case IOCTL_SW_READY_ON
:
208 moxart_gpio_set(SW_READY_GPIO
, GPIO_EM1240_LOW
);
210 case IOCTL_SW_READY_OFF
:
211 moxart_gpio_set(SW_READY_GPIO
, GPIO_EM1240_HIGH
);
219 static int gpio_open(struct inode
*inode
, struct file
*file
)
221 if (MINOR(inode
->i_rdev
) == MOXA_MISC_MINOR
)
226 static int gpio_release(struct inode
*inode
, struct file
*file
)
231 static const struct file_operations gpio_fops
= {
232 .owner
= THIS_MODULE
,
236 .release
= gpio_release
,
239 static struct miscdevice gpio_dev
= {
245 static void __exit
gpio_exit(void)
249 spin_lock_irqsave(&reset_lock
, flags
);
250 del_timer(&reset_timer
);
251 spin_unlock_irqrestore(&reset_lock
, flags
);
252 misc_deregister(&gpio_dev
);
255 static int __init
gpio_init(void)
259 pr_info("MOXART GPIO (LEDs and RESET pin) driver\n");
260 if (misc_register(&gpio_dev
)) {
261 pr_info(": misc_register failed!\n");
265 moxart_gpio_mp_set(SW_READY_GPIO
|SW_RESET_GPIO
);
266 moxart_gpio_inout(SW_READY_GPIO
, GPIO_EM1240_OUTPUT
);
267 moxart_gpio_inout(SW_RESET_GPIO
, GPIO_EM1240_INPUT
);
268 moxart_gpio_set(SW_READY_GPIO
, GPIO_EM1240_HIGH
);
270 INIT_WORK(&reset_pin_detected_queue
, reset_pin_detected
);
271 spin_lock_init(&reset_lock
);
272 spin_lock_init(&gpio_lock
);
273 spin_lock_irqsave(&reset_lock
, flags
);
276 init_timer(&reset_timer
);
277 reset_timer
.function
= reset_poll
;
278 reset_timer
.expires
= jiffies
+ RESET_POLL_TIME
;
279 add_timer(&reset_timer
);
280 spin_unlock_irqrestore(&reset_lock
, flags
);
285 module_init(gpio_init
);
286 module_exit(gpio_exit
);
288 MODULE_DESCRIPTION("MOXART GPIO (LEDs and RESET pin) driver");
289 MODULE_LICENSE("GPL");