source: src/linux/pb42/linux-2.6.23/arch/mips/ar7100/proc_gpio.c @ 14511

Last change on this file since 14511 was 14511, checked in by BrainSlayer, 3 years ago

wndr3700 usb led

File size: 8.4 KB
Line 
1/*
2 * proc_gpio: AR5315 GPIO pins in /proc/gpio/
3 * by olg
4 * modification for AR7100 support by Sebastian Gottschall <s.gottschall@newmedia-net.de>
5 * GPL'ed
6 * some code stolen from Yoshinori Sato <ysato@users.sourceforge.jp>
7 *
8 *  This program is free software; you can redistribute it and/or modify it
9 *  under the terms of the GNU General Public License version 2 as published
10 *  by the Free Software Foundation.
11 */
12
13#include <linux/autoconf.h>
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/types.h>
17#include <linux/stddef.h>
18#include <linux/proc_fs.h>
19#include <linux/kernel.h>
20#include <linux/string.h>
21#include <linux/fs.h>
22#include <asm/uaccess.h>        /* for copy_from_user */
23
24#include "ar7100.h"
25
26#define PROCFS_MAX_SIZE 64
27extern const char *get_arch_type(void);
28struct proc_dir_entry *proc_gpio, *gpio_dir;
29
30//Masks for data exchange through "void *data" pointer
31#define GPIO_IN (1<<5)
32#define GPIO_OUT (1<<6)
33#define GPIO_DIR (1<<7)
34#define PIN_MASK 0x1f
35#define GPIO_CR_M(x)                (1 << (x))  /* mask for i/o */
36
37static void cleanup_proc(void);
38void ar7100_set_gpio(int gpio, int val)
39{
40        u32 reg = ar7100_reg_rd(AR7100_GPIO_OE);
41        reg |= 1 << gpio;
42        ar7100_reg_wr(AR7100_GPIO_OE, reg);
43        (void)ar7100_reg_rd(AR7100_GPIO_OE);    /* flush write to hardware */
44        reg = ar7100_reg_rd(AR7100_GPIO_OUT);
45        if (val)
46                reg |= 1 << gpio;
47        else
48                reg &= ~(1 << gpio);
49        ar7100_reg_wr(AR7100_GPIO_OUT, reg);
50}
51
52int ar7100_get_gpio(int gpio)
53{
54        u32 reg = ar7100_reg_rd(AR7100_GPIO_OE);
55        reg &= ~(1 << gpio);
56        ar7100_reg_wr(AR7100_GPIO_OE, reg);
57        reg = ar7100_reg_rd(AR7100_GPIO_IN);
58        if (reg & (1 << gpio))
59                return 1;
60        else
61                return 0;
62}
63
64void
65ar7100_gpio_config_output(int gpio)
66{
67    ar7100_reg_rmw_set(AR7100_GPIO_OE, (1 << gpio));
68    (void)ar7100_reg_rd(AR7100_GPIO_OE);        /* flush write to hardware */
69}
70
71void
72ar7100_gpio_config_input(int gpio)
73{
74    ar7100_reg_rmw_clear(AR7100_GPIO_OE, (1 << gpio));
75    (void)ar7100_reg_rd(AR7100_GPIO_OE);        /* flush write to hardware */
76}
77
78void
79ar7100_gpio_out_val(int gpio, int val)
80{
81    if (val & 0x1) {
82        ar7100_reg_rmw_set(AR7100_GPIO_OUT, (1 << gpio));
83    }
84    else {
85        ar7100_reg_rmw_clear(AR7100_GPIO_OUT, (1 << gpio));
86    }
87    (void)ar7100_reg_rd(AR7100_GPIO_OUT);       /* flush write to hardware */
88}
89
90int
91ar7100_gpio_in_val(int gpio)
92{
93    return((1 << gpio) & (ar7100_reg_rd(AR7100_GPIO_IN)));
94}
95
96
97
98EXPORT_SYMBOL(ar7100_set_gpio);
99EXPORT_SYMBOL(ar7100_get_gpio);
100EXPORT_SYMBOL(ar7100_gpio_config_output);
101EXPORT_SYMBOL(ar7100_gpio_config_input);
102EXPORT_SYMBOL(ar7100_gpio_in_val);
103EXPORT_SYMBOL(ar7100_gpio_out_val);
104
105#define USB_LED_OFF 1
106#define USB_LED_ON 0
107
108void ap_usb_led_on(void)
109{
110#ifdef CONFIG_WNDR3700
111        ar7100_reg_rmw_set(AR7100_RESET, AR7100_RESET_GE1_PHY);
112#else
113#ifdef AP_USB_LED_GPIO
114        ar7100_set_gpio(AP_USB_LED_GPIO, USB_LED_ON);
115#endif
116#endif
117}
118EXPORT_SYMBOL(ap_usb_led_on);
119
120void ap_usb_led_off(void)
121{
122#ifdef CONFIG_WNDR3700
123        ar7100_reg_rmw_clear(AR7100_RESET, AR7100_RESET_GE1_PHY);
124#else
125#ifdef AP_USB_LED_GPIO
126        ar7100_set_gpio(AP_USB_LED_GPIO, USB_LED_OFF);
127#endif
128#endif
129}
130EXPORT_SYMBOL(ap_usb_led_off);
131
132
133
134
135#define NXP_74HC153_NUM_GPIOS   8
136#define NXP_74HC153_S0_MASK     0x1
137#define NXP_74HC153_S1_MASK     0x2
138#define NXP_74HC153_BANK_MASK   0x4
139
140#define WZRHPG300NH_GPIO_74HC153_S0     9
141#define WZRHPG300NH_GPIO_74HC153_S1     11
142#define WZRHPG300NH_GPIO_74HC153_1Y     12
143#define WZRHPG300NH_GPIO_74HC153_2Y     14
144
145#define WZRHPG300NH_GPIO_EXP_BASE       23
146#define WZRHPG300NH_GPIO_BTN_AOSS       (WZRHPG300NH_GPIO_EXP_BASE + 0)
147#define WZRHPG300NH_GPIO_BTN_RESET      (WZRHPG300NH_GPIO_EXP_BASE + 1)
148#define WZRHPG300NH_GPIO_BTN_ROUTER_ON  (WZRHPG300NH_GPIO_EXP_BASE + 2)
149#define WZRHPG300NH_GPIO_BTN_QOS_ON     (WZRHPG300NH_GPIO_EXP_BASE + 3)
150#define WZRHPG300NH_GPIO_BTN_USB        (WZRHPG300NH_GPIO_EXP_BASE + 5)
151#define WZRHPG300NH_GPIO_BTN_ROUTER_AUTO (WZRHPG300NH_GPIO_EXP_BASE + 6)
152#define WZRHPG300NH_GPIO_BTN_QOS_OFF    (WZRHPG300NH_GPIO_EXP_BASE + 7)
153
154static int nxp_74hc153_get_value(unsigned offset)
155{
156        unsigned s0;
157        unsigned s1;
158        unsigned pin;
159        int ret;
160
161        s0 = !!(offset & NXP_74HC153_S0_MASK);
162        s1 = !!(offset & NXP_74HC153_S1_MASK);
163        pin = (offset & NXP_74HC153_BANK_MASK) ? WZRHPG300NH_GPIO_74HC153_2Y
164            : WZRHPG300NH_GPIO_74HC153_1Y;
165
166        ar7100_set_gpio(WZRHPG300NH_GPIO_74HC153_S0, s0);
167        ar7100_set_gpio(WZRHPG300NH_GPIO_74HC153_S1, s1);
168        ret = ar7100_get_gpio(pin);
169
170        return ret;
171}
172
173//The buffer used to store the data returned by the proc file
174static char procfs_buffer[PROCFS_MAX_SIZE];
175static unsigned long procfs_buffer_size = 0;
176
177static int
178gpio_proc_read(char *buf, char **start, off_t offset,
179               int len, int *eof, void *data)
180{
181        int val;
182        unsigned int pin = (unsigned int)data & PIN_MASK;
183        if (pin >= 23 && pin <= 31) {
184                val = nxp_74hc153_get_value(pin - 23);
185        //      printk(KERN_EMERG "value for pin %d = %d\n", pin, val);
186                if (val)
187                        buf[0] = '1';
188                else
189                        buf[0] = '0';
190                buf[1] = 0;
191                *eof = 1;
192                return (2);
193        }
194        u32 reg = 0;
195        if ((unsigned int)data & GPIO_IN)
196                reg = ar7100_reg_rd(AR7100_GPIO_IN);
197        if ((unsigned int)data & GPIO_OUT)
198                reg = ar7100_reg_rd(AR7100_GPIO_OUT);
199        if ((unsigned int)data & GPIO_DIR)
200                reg = ar7100_reg_rd(AR7100_GPIO_OE);
201
202        if (GPIO_CR_M(((unsigned int)data) & PIN_MASK) & reg)
203                buf[0] = '1';
204        else
205                buf[0] = '0';
206        buf[1] = 0;
207
208        *eof = 1;
209
210        return (2);
211
212}
213
214static int
215gpio_proc_info_read(char *buf, char **start, off_t offset,
216                    int len, int *eof, void *data)
217{
218        *eof = 1;
219        return (sprintf
220                (buf, "GPIO_IN   %#08X \nGPIO_OUT  %#08X \nGPIO_DIR  %#08X \n",
221                 ar7100_reg_rd(AR7100_GPIO_IN), ar7100_reg_rd(AR7100_GPIO_OUT),
222                 ar7100_reg_rd(AR7100_GPIO_OE)));
223}
224
225static int
226gpio_proc_write(struct file *file, const char *buffer, unsigned long count,
227                void *data)
228{
229        u32 reg = 0;
230
231        /* get buffer size */
232        procfs_buffer_size = count;
233        if (procfs_buffer_size > PROCFS_MAX_SIZE) {
234                procfs_buffer_size = PROCFS_MAX_SIZE;
235        }
236        /* write data to the buffer */
237        if (copy_from_user(procfs_buffer, buffer, procfs_buffer_size)) {
238                return -EFAULT;
239        }
240
241        procfs_buffer[procfs_buffer_size] = 0;
242
243        if ((unsigned int)data & GPIO_IN)
244                reg = ar7100_reg_rd(AR7100_GPIO_IN);
245        if ((unsigned int)data & GPIO_OUT)
246                reg = ar7100_reg_rd(AR7100_GPIO_OUT);
247        if ((unsigned int)data & GPIO_DIR)
248                reg = ar7100_reg_rd(AR7100_GPIO_OE);
249
250        if (procfs_buffer[0] == '0' || procfs_buffer[0] == 'i')
251                reg = reg & ~(GPIO_CR_M(((unsigned int)data) & PIN_MASK));
252        if (procfs_buffer[0] == '1' || procfs_buffer[0] == 'o')
253                reg = reg | GPIO_CR_M(((unsigned int)data) & PIN_MASK);
254
255        if ((unsigned int)data & GPIO_IN) {
256                ar7100_reg_wr(AR7100_GPIO_IN, reg);
257        }
258        if ((unsigned int)data & GPIO_OUT) {
259                ar7100_reg_wr(AR7100_GPIO_OUT, reg);
260        }
261        if ((unsigned int)data & GPIO_DIR) {
262                ar7100_reg_wr(AR7100_GPIO_OE, reg);
263        }
264
265        return procfs_buffer_size;
266}
267
268static __init int register_proc(void)
269{
270        unsigned char i, flag = 0;
271        char proc_name[32];
272        int gpiocount = 32;
273
274        /* create directory gpio */
275        gpio_dir = proc_mkdir("gpio", NULL);
276        if (gpio_dir == NULL)
277                goto fault;
278        gpio_dir->owner = THIS_MODULE;
279
280        for (i = 0; i < gpiocount * 3; i++)     //create for every GPIO "x_in"," x_out" and "x_dir"
281        {
282                if (i / gpiocount == 0) {
283                        flag = GPIO_IN;
284                        sprintf(proc_name, "%i_in", i);
285                }
286                if (i / gpiocount == 1) {
287                        flag = GPIO_OUT;
288                        sprintf(proc_name, "%i_out", i % gpiocount);
289                }
290                if (i / gpiocount == 2) {
291                        flag = GPIO_DIR;
292                        sprintf(proc_name, "%i_dir", i % gpiocount);
293                }
294
295                proc_gpio = create_proc_entry(proc_name, S_IRUGO, gpio_dir);
296                if (proc_gpio) {
297                        proc_gpio->read_proc = gpio_proc_read;
298                        proc_gpio->write_proc = gpio_proc_write;
299                        proc_gpio->owner = THIS_MODULE;
300                        proc_gpio->data = ((i % gpiocount) | flag);
301                } else
302                        goto fault;
303
304        }
305
306        proc_gpio = create_proc_entry("info", S_IRUGO, gpio_dir);
307        if (proc_gpio) {
308                proc_gpio->read_proc = gpio_proc_info_read;
309                proc_gpio->owner = THIS_MODULE;
310        } else
311                goto fault;
312
313        printk(KERN_NOTICE
314               "gpio_proc: module loaded and /proc/gpio/ created\n");
315        return 0;
316
317fault:
318        cleanup_proc();
319        return -EFAULT;
320}
321
322static void cleanup_proc(void)
323{
324        unsigned char i;
325        char proc_name[32];
326        int gpiocount = 32;
327
328        for (i = 0; i < gpiocount; i++) {
329                sprintf(proc_name, "%i_in", i);
330                remove_proc_entry(proc_name, gpio_dir);
331                sprintf(proc_name, "%i_out", i);
332                remove_proc_entry(proc_name, gpio_dir);
333                sprintf(proc_name, "%i_dir", i);
334                remove_proc_entry(proc_name, gpio_dir);
335        }
336        remove_proc_entry("info", gpio_dir);
337        remove_proc_entry("gpio", NULL);
338        printk(KERN_INFO "gpio_proc: unloaded and /proc/gpio/ removed\n");
339
340}
341
342module_init(register_proc);
343module_exit(cleanup_proc);
344
345MODULE_AUTHOR("Sebastian Gottschall");
346MODULE_DESCRIPTION("AR7100 GPIO pins in /proc/gpio/");
347MODULE_LICENSE("GPL");
Note: See TracBrowser for help on using the repository browser.