56805e55bbe4a160ca34e3896d4748af781a842c
[openwrt.git] / target / linux / lantiq / files / arch / mips / lantiq / svip / mux.c
1 /************************************************************************
2  *
3  * Copyright (c) 2007
4  * Infineon Technologies AG
5  * St. Martin Strasse 53; 81669 Muenchen; Germany
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version
10  * 2 of the License, or (at your option) any later version.
11  *
12  ************************************************************************/
13
14 #include <linux/module.h>
15 #include <linux/types.h>
16 #include <linux/kernel.h>
17 #include <linux/proc_fs.h>
18 #include <linux/init.h>
19 #include <asm/addrspace.h>
20 #include <linux/platform_device.h>
21
22 #include <lantiq_soc.h>
23 #include <svip_mux.h>
24 #include <sys1_reg.h>
25 #include <sys2_reg.h>
26 #include <svip_pms.h>
27
28 #define DRV_NAME "ltq_mux"
29
30 static void ltq_mux_port_init(const int port,
31                               const struct ltq_mux_pin *pins,
32                               const int pin_max)
33 {
34         unsigned int i;
35
36         for (i = 0; i < pin_max; i++)
37                 ltq_gpio_configure(port,
38                                    i,
39                                    pins[i].dirin,
40                                    pins[i].puen,
41                                    pins[i].altsel0,
42                                    pins[i].altsel1);
43 }
44
45 static int ltq_mux_probe(struct platform_device *pdev)
46 {
47         struct ltq_mux_settings *mux_settings = dev_get_platdata(&pdev->dev);
48
49         if (mux_settings->mux_p0)
50                 ltq_mux_port_init(0,
51                                   mux_settings->mux_p0,
52                                   LTQ_MUX_P0_PINS);
53
54         if (mux_settings->mux_p1)
55                 ltq_mux_port_init(1,
56                                   mux_settings->mux_p1,
57                                   LTQ_MUX_P1_PINS);
58
59         if (mux_settings->mux_p2)
60                 ltq_mux_port_init(2,
61                                   mux_settings->mux_p2,
62                                   LTQ_MUX_P2_PINS);
63
64         if (mux_settings->mux_p3)
65                 ltq_mux_port_init(3,
66                                   mux_settings->mux_p3,
67                                   LTQ_MUX_P3_PINS);
68
69         if (mux_settings->mux_p4)
70                 ltq_mux_port_init(4,
71                                   mux_settings->mux_p4,
72                                   LTQ_MUX_P4_PINS);
73
74         return 0;
75 }
76
77 int ltq_mux_read_procmem(char *buf, char **start, off_t offset,
78                          int count, int *eof, void *data)
79 {
80         int len = 0;
81         int t = 0, i = 0;
82         u32 port_clk[5] = {
83                 SYS1_CLKENR_PORT0,
84                 SYS1_CLKENR_PORT1,
85                 SYS1_CLKENR_PORT2,
86                 SYS1_CLKENR_PORT3,
87                 SYS2_CLKENR_PORT4,
88         };
89
90 #define PROC_PRINT(fmt, args...) \
91         do { \
92                 int c_len = 0; \
93                 c_len = snprintf(buf + len, count - len, fmt, ## args); \
94                 if (c_len <= 0) \
95                         goto out; \
96                 if (c_len >= (count - len)) { \
97                         len += (count - len); \
98                         goto out; \
99                 } \
100                 len += c_len; \
101                 if (offset > 0) { \
102                         if (len > offset) { \
103                                 len -= offset; \
104                                 memmove(buf, buf + offset, len); \
105                                 offset = 0; \
106                         } else { \
107                                 offset -= len; \
108                                 len = 0; \
109                         } \
110                 } \
111         } while (0)
112
113         PROC_PRINT("\nVINETIC-SVIP Multiplex Settings\n");
114         PROC_PRINT("              3         2         1         0\n");
115         PROC_PRINT("             10987654321098765432109876543210\n");
116         PROC_PRINT("             --------------------------------\n");
117
118         for (i = 0; i < ARRAY_SIZE(port_clk); i++) {
119                 if (i < 4) {
120                         if (!svip_sys1_clk_is_enabled(port_clk[i]))
121                                 continue;
122                 } else {
123                         if (!svip_sys2_clk_is_enabled(port_clk[i]))
124                                 continue;
125                 }
126
127                 PROC_PRINT("P%d.%-10s", i, "DIR:");
128
129                 for (t = 31; t != -1; t--)
130                         PROC_PRINT("%d", ltq_port_get_dir(i, t) == 1 ? 1 : 0);
131                 PROC_PRINT("\n");
132
133                 PROC_PRINT("P%d.%-10s", i, "PUEN:");
134                 for (t = 31; t != -1; t--)
135                         PROC_PRINT("%d", ltq_port_get_puden(i, t) == 1 ? 1 : 0);
136                 PROC_PRINT("\n");
137
138                 PROC_PRINT("P%d.%-10s", i, "ALTSEL0:");
139                 for (t = 31; t != -1; t--)
140                         PROC_PRINT("%d",
141                                    ltq_port_get_altsel0(i, t) == 1 ? 1 : 0);
142                 PROC_PRINT("\n");
143
144                 PROC_PRINT("P%d.%-10s", i, "ALTSEL1:");
145                 for (t = 31; t != -1; t--)
146                         PROC_PRINT("%d",
147                                    ltq_port_get_altsel1(i, t) == 1 ? 1 : 0);
148                 PROC_PRINT("\n\n");
149         }
150
151 out:
152         if (len < 0) {
153                 len = 0;
154                 *eof = 1;
155         } else if (len < count) {
156                 *eof = 1;
157         } else {
158                 len = count;
159         }
160
161         *start = buf;
162
163         return len;
164 }
165
166 static struct platform_driver ltq_mux_driver = {
167         .probe = ltq_mux_probe,
168         .driver = {
169                 .name = DRV_NAME,
170                 .owner = THIS_MODULE,
171         },
172 };
173
174 int __init ltq_mux_init(void)
175 {
176         int ret = platform_driver_register(&ltq_mux_driver);
177         if (ret) {
178                 printk(KERN_INFO DRV_NAME
179                        ": Error registering platform driver!");
180                 return ret;
181         }
182
183         return create_proc_read_entry("driver/ltq_mux", 0, NULL,
184                                       ltq_mux_read_procmem, NULL) == NULL;
185 }
186
187 module_init(ltq_mux_init);