source: src/linux/universal/linux-4.9/arch/arm/mach-brcm-hnd/gpio.c @ 31574

Last change on this file since 31574 was 31574, checked in by brainslayer, 8 weeks ago

kernel 4.9 update

File size: 7.0 KB
Line 
1/*
2 * GPIO char driver
3 *
4 * Copyright (C) 2008, Broadcom Corporation
5 * All Rights Reserved.
6 *
7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
11 *
12 * $Id: gpio.c,v 1.5 2008/04/03 03:49:45 Exp $
13 */
14
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/fs.h>
18#include <linux/miscdevice.h>
19#include <asm/uaccess.h>
20
21#include <typedefs.h>
22#include <bcmutils.h>
23#include <siutils.h>
24#include <bcmdevs.h>
25#include <bcmnvram.h>
26#include "ext_io.h"
27
28static si_t *gpio_sih;
29static int gpio_major;
30static struct {
31        char *name;
32} gpio_file[] = {
33        {
34        "in"}, {
35        "out"}, {
36        "outen"}, {
37        "control"}, {
38        "hc595"}
39};
40
41static int gpio_init_flag = 0;
42static int __init gpio_init(void);
43void set_hc595(uint32 pin, uint32 value);
44void set_hc595_reset(void);
45void set_hc595_core(si_t *sih);
46
47
48static int gpio_open(struct inode *inode, struct file *file)
49{
50        if (MINOR(inode->i_rdev) > ARRAYSIZE(gpio_file))
51                return -ENODEV;
52
53        MOD_INC_USE_COUNT;
54        return 0;
55}
56
57static int gpio_release(struct inode *inode, struct file *file)
58{
59        MOD_DEC_USE_COUNT;
60        return 0;
61}
62
63static ssize_t gpio_read(struct file *file, char *buf, size_t count, loff_t * ppos)
64{
65        u32 val;
66        switch (MINOR(file_inode(file)->i_rdev)) {
67        case 0:
68                val = si_gpioin(gpio_sih);
69                break;
70        case 1:
71                val = si_gpioout(gpio_sih, 0, 0, GPIO_APP_PRIORITY);
72                break;
73        case 2:
74                val = si_gpioouten(gpio_sih, 0, 0, GPIO_APP_PRIORITY);
75                break;
76        case 3:
77                val = si_gpiocontrol(gpio_sih, 0, 0, GPIO_APP_PRIORITY);
78                break;
79        default:
80                return -ENODEV;
81        }
82
83        if (put_user(val, (u32 *)buf))
84                return -EFAULT;
85
86        return sizeof(val);
87}
88
89int gpio_kernel_api(unsigned int cmd, unsigned int mask, unsigned int val)
90{
91
92        if (gpio_init_flag != 1) {
93                if (gpio_init() != 0)
94                        return -EFAULT;
95        }
96
97        switch (cmd) {
98        case 0:
99                si_gpioout(gpio_sih, mask, val, GPIO_HI_PRIORITY);
100                break;
101        case 1:
102                si_gpioouten(gpio_sih, mask, val, GPIO_HI_PRIORITY);
103                break;
104        case 3:
105                si_gpioreserve(gpio_sih, mask, GPIO_HI_PRIORITY);
106                break;
107        default:
108                printk("Unknown gpio_kenerl_api command\n");
109                break;
110        }
111
112        return 0;
113}
114
115EXPORT_SYMBOL(gpio_kernel_api);
116
117static ssize_t gpio_write(struct file *file, const char *buf, size_t count, loff_t * ppos)
118{
119        u32 val;
120
121        if (get_user(val, (u32 *)buf))
122                return -EFAULT;
123        switch (MINOR(file_inode(file)->i_rdev)) {
124        case 0:
125                return -EACCES;
126        case 1:
127                si_gpioout(gpio_sih, ~0, val, GPIO_HI_PRIORITY);
128                break;
129        case 2:
130                si_gpioouten(gpio_sih, ~0, val, GPIO_HI_PRIORITY);
131                break;
132        case 3:
133                si_gpiocontrol(gpio_sih, ~0, val, GPIO_HI_PRIORITY);
134                break;
135        case 4:
136                set_hc595(val >> 4, val & 0xf);
137                break;
138        default:
139                return -ENODEV;
140        }
141
142        return sizeof(val);
143}
144
145static struct file_operations gpio_fops = {
146      owner:THIS_MODULE,
147      open:gpio_open,
148      release:gpio_release,
149      read:gpio_read,
150      write:gpio_write,
151};
152
153extern int iswrt350n;
154extern int iswrt300n11;
155int isac66 = 0;
156int isac68 = 0;
157int isbuffalo = 0;
158int isbuffalowxr = 0;
159int isdefault = 0;
160
161static int __init gpio_init(void)
162{
163        int i;
164        int gpios = 0;
165        printk(KERN_INFO "init gpio code\n");
166        if (!(gpio_sih = si_kattach(SI_OSH)))
167                return -ENODEV;
168
169        si_gpiosetcore(gpio_sih);
170        set_hc595_core(gpio_sih);
171        if ((gpio_major = register_chrdev(127, "gpio", &gpio_fops)) < 0) {
172                return gpio_major;
173        }
174
175        uint boardnum = bcm_strtoul(nvram_safe_get("boardnum"), NULL, 0);
176
177        if (boardnum == 00 && nvram_match("boardtype", "0xF646")
178            && nvram_match("boardrev", "0x1100")
179            && nvram_match("melco_id", "RD_BB12068")) {
180                printk(KERN_EMERG "Buffalo WZR-1750DHP\n");
181                isbuffalo = 1;
182                set_hc595_reset();
183                gpio_init_flag = 1;
184                return 0;
185
186        }
187
188        if (boardnum == 00 && nvram_match("boardtype", "0x0665")
189            && nvram_match("boardrev", "0x1103")
190            && nvram_match("melco_id", "RD_BB13049")) {
191                printk(KERN_EMERG "Buffalo WXR-1900DHP\n");
192                isbuffalowxr = 1;
193                gpio_init_flag = 1;
194                return 0;
195
196        }
197
198        if ((!strncmp(nvram_safe_get("boardnum"),"2013",4) || !strncmp(nvram_safe_get("boardnum"),"2014",4)) && nvram_match("boardtype", "0x0646")
199            && nvram_match("boardrev", "0x1110")
200            && nvram_match("0:rxchain", "7")) {
201                printk(KERN_EMERG "Buffalo WZR-900DHP\n");
202                isbuffalo = 1;
203                set_hc595_reset();
204                gpio_init_flag = 1;
205                return 0;
206        }
207
208        if ((!strncmp(nvram_safe_get("boardnum"),"2013",4) || !strncmp(nvram_safe_get("boardnum"),"2014",4)) && nvram_match("boardtype", "0x0646")
209            && nvram_match("boardrev", "0x1110")
210            && nvram_match("0:rxchain", "3")) {
211                printk(KERN_EMERG "Buffalo WZR-600DHP2\n");
212                isbuffalo = 1;
213                set_hc595_reset();
214                gpio_init_flag = 1;
215                return 0;
216        }
217
218        if ((boardnum == 0) && nvram_match("boardtype", "0x0646") && (nvram_match("boardrev", "0x1100"))) {
219                printk(KERN_EMERG "Asus-RT-AC56U init\n");
220                isac66 = 1;
221        }
222
223        if (nvram_match("model","RT-AC68U")) {
224                printk(KERN_EMERG "Asus-RT-AC68U init\n");
225                isac68 = 1;
226        } else if ((boardnum != 24) && nvram_match("boardtype", "0x0646") && (nvram_match("boardrev", "0x1100"))) {
227                printk(KERN_EMERG "Asus-RT-AC68U init\n");
228                isac68 = 1;
229        }
230
231        if ((boardnum == 24) && nvram_match("boardtype", "0x0646") && nvram_match("boardrev", "0x1110") && !nvram_match("gpio6", "wps_led")) {
232                printk(KERN_EMERG "DLink DIR-868 init\n");
233                isac66 = 1;
234        }
235
236        if ((boardnum == 679) && nvram_match("boardtype", "0x0646") && (nvram_match("boardrev", "0x1110"))) {
237                printk(KERN_EMERG "Netgear AC1450/R6250/R6300v2/EX6200 init\n");
238                gpios = 1<<0 | 1<<1 | 1<<2 | 1<<3 | 1<<4 | 1<<5 | 1<<6 | 1<<7 | 1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<15;
239        }
240       
241        if ((boardnum == 32) && nvram_match("boardtype", "0x0646") && (nvram_match("boardrev", "0x1601"))) {
242                printk(KERN_EMERG "Netgear R6400 init\n");
243                gpios = 1<<0 | 1<<1 | 1<<2 | 1<<3 | 1<<4 | 1<<5 | 1<<6 | 1<<7 | 1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<15;
244        }
245
246        if ((boardnum == 32) && nvram_match("boardtype", "0x0665") && (nvram_match("boardrev", "0x1301"))) {
247                printk(KERN_EMERG "Netgear R7000 init\n");
248                gpios = 1<<0 | 1<<1 | 1<<2 | 1<<3 | 1<<4 | 1<<5 | 1<<6 | 1<<7 | 1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<15;
249        }
250       
251        if ((boardnum == 32) && nvram_match("boardtype", "0x0665") && (nvram_match("boardrev", "0x1101"))) {
252                printk(KERN_EMERG "Netgear R8000 init\n");
253                gpios = 1<<0 | 1<<1 | 1<<2 | 1<<3 | 1<<4 | 1<<5 | 1<<6 | 1<<7 | 1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<15;
254        }
255       
256        if ((boardnum == 32) && nvram_match("boardtype", "0x072F") && (nvram_match("boardrev", "0x1101"))) {
257                printk(KERN_EMERG "Netgear R8500 init\n");
258                gpios = 1<<0 | 1<<1 | 1<<2 | 1<<3 | 1<<4 | 1<<5 | 1<<6 | 1<<7 | 1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<12 | 1<<13 | 1<<14 | 1<<15 | 1<<16 | 1<<17 | 1<<18 | 1<<19 | 1<<20 | 1<<21 | 1<<22 | 1<<23  | 1<<24 ;
259        }
260        if (nvram_match("model","RT-AC1200G+")) {
261                printk(KERN_EMERG " Init Asus RT-AC1200G+\n");
262                isdefault = 1;
263        }       
264       
265
266        for (i = 0; i < 32; i++) {
267                if (gpios & (1<<i)) {
268                        si_gpioreserve(gpio_sih, 1 << i, GPIO_APP_PRIORITY);
269                }
270        }
271
272        gpio_init_flag = 1;
273        return 0;
274}
275
276static void __exit gpio_exit(void)
277{
278        int i;
279
280        si_detach(gpio_sih);
281}
282
283module_init(gpio_init);
284module_exit(gpio_exit);
Note: See TracBrowser for help on using the repository browser.