[adm8668] add a gpiolib driver
[openwrt.git] / target / linux / adm8668 / files / arch / mips / adm8668 / proc.c
1 /*
2  * Copyright (C) 2010 Scott Nicholas <neutronscott@scottn.us>
3  *
4  * This file is subject to the terms and conditions of the GNU General Public
5  * License.  See the file "COPYING" in the main directory of this archive
6  * for more details.
7  */
8
9 #include <linux/module.h>
10 #include <linux/kernel.h>
11 #include <linux/init.h>
12 #include <linux/proc_fs.h>
13 #include <asm/uaccess.h>
14 #include <adm8668.h>
15
16 int adm8668_sesled_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
17 {
18         char buf[8];
19         int num;
20
21         num = (count < 8) ? count : 8;
22
23         if (copy_from_user(buf, buffer, num))
24         {
25                 printk("copy_from_user failed");
26                 return -EFAULT;
27         }
28         num = simple_strtoul(buf, NULL, 16);
29         switch (num)
30         {
31                 case 0:
32                         GPIO_SET_LOW(0);
33                         CRGPIO_SET_LOW(2);
34                         break;
35                 case 1:
36                         GPIO_SET_LOW(0);
37                         CRGPIO_SET_HI(2);
38                         break;
39                 case 2:
40                         GPIO_SET_HI(0);
41                         CRGPIO_SET_HI(2);
42                         break;
43                 default:
44                         break;
45         }
46
47         return count;
48 }
49
50 int adm8668_sesled_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *data)
51 {
52         int len = 0;
53         int led_state = 0;
54
55         led_state = (ADM8668_CONFIG_REG(CRGPIO_REG) & 0x100) ? 1 : 0;
56         led_state += (ADM8668_WLAN_REG(GPIO_REG) & 0x40) ? 2 : 0;
57         len += sprintf(buf+len, "%s\n",
58                 (led_state&1) ?
59                         ((led_state&2) ? "ORANGE" : "GREEN") : "OFF");
60
61         return len;
62 }
63
64 int adm8668_button_read_proc(char *buf, char **start, off_t offset,
65         int count, int *eof, void *data)
66 {
67         int len = 0;
68         int read_once = ADM8668_CONFIG_REG(CRGPIO_REG);
69         int button_flip = (read_once >> 20) & 0x3;
70         int button_state = read_once & 0x3;
71
72         len += sprintf(buf+len, "SES: %s %s\nRESET: %s %s\n",
73                 (button_state&2) ? "UP" : "DOWN",
74                 (button_flip&2) ? "FLIP" : "",
75                 (button_state&1) ? "UP" : "DOWN",
76                 (button_flip&1) ? "FLIP" : "");
77
78         return len;
79 }
80
81 int __init adm8668_init_proc(void)
82 {
83         struct proc_dir_entry *adm8668_proc_dir = NULL;
84         struct proc_dir_entry *sesled = NULL;
85         int __maybe_unused bogus;
86
87         /* these are known to be lights. rest are input...? */
88         ADM8668_CONFIG_REG(CRGPIO_REG)  = GPIO2_OUTPUT_ENABLE;
89         ADM8668_WLAN_REG(GPIO_REG)      = GPIO0_OUTPUT_ENABLE;
90
91         /* inital read off of the flipper switcher on the button thingie */
92         bogus = ADM8668_CONFIG_REG(CRGPIO_REG);
93
94         adm8668_proc_dir = proc_mkdir("adm8668", 0);
95         if (adm8668_proc_dir == NULL) {
96                 printk(KERN_ERR "ADM8668 proc: unable to create proc dir.\n");
97                 return 0;
98         }
99         create_proc_read_entry("buttons", 0444, adm8668_proc_dir,
100                                         adm8668_button_read_proc, NULL);
101         sesled = create_proc_entry("sesled", S_IRUGO|S_IWUGO, adm8668_proc_dir);
102         if (sesled) {
103                 sesled->read_proc = adm8668_sesled_read_proc;
104                 sesled->write_proc = adm8668_sesled_write_proc;
105         }
106
107         return 0;
108 }
109
110 module_init(adm8668_init_proc);
111
112 MODULE_LICENSE("GPL");
113 MODULE_AUTHOR("Scott Nicholas <neutronscott@scottn.us>");
114 MODULE_DESCRIPTION("ADM8668 ghetto button driver");