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

Last change on this file since 31707 was 31707, checked in by brainslayer, 10 days ago

compiles on northstar, but nand driver will likelly not work yet. still something todo

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 __init 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.