]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - sys/arm/freescale/imx/imx51_iomux.c
MFC 264977:
[FreeBSD/stable/10.git] / sys / arm / freescale / imx / imx51_iomux.c
1 /*      $NetBSD: imx51_iomux.c,v 1.3 2012/04/15 09:51:31 bsh Exp $      */
2
3 /*
4  * Copyright (c) 2009, 2010  Genetec Corporation.  All rights reserved.
5  * Written by Hashimoto Kenichi for Genetec Corporation.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GENETEC CORPORATION
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 /*-
30  * Copyright (c) 2012, 2013 The FreeBSD Foundation
31  * All rights reserved.
32  *
33  * Portions of this software were developed by Oleksandr Rybalko
34  * under sponsorship from the FreeBSD Foundation.
35  *
36  * Redistribution and use in source and binary forms, with or without
37  * modification, are permitted provided that the following conditions
38  * are met:
39  * 1.   Redistributions of source code must retain the above copyright
40  *      notice, this list of conditions and the following disclaimer.
41  * 2.   Redistributions in binary form must reproduce the above copyright
42  *      notice, this list of conditions and the following disclaimer in the
43  *      documentation and/or other materials provided with the distribution.
44  *
45  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
46  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
49  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55  * SUCH DAMAGE.
56  */
57
58 #include <sys/cdefs.h>
59 __FBSDID("$FreeBSD$");
60
61 #include <sys/param.h>
62 #include <sys/systm.h>
63 #include <sys/bus.h>
64 #include <sys/kernel.h>
65 #include <sys/module.h>
66 #include <sys/malloc.h>
67 #include <sys/rman.h>
68
69 #include <machine/bus.h>
70 #include <machine/fdt.h>
71
72 #include <dev/fdt/fdt_common.h>
73 #include <dev/ofw/openfirm.h>
74 #include <dev/ofw/ofw_bus.h>
75 #include <dev/ofw/ofw_bus_subr.h>
76
77 #include <arm/freescale/imx/imx51_iomuxvar.h>
78 #include <arm/freescale/imx/imx51_iomuxreg.h>
79
80
81 #define IOMUX_WRITE(_sc, _r, _v)                                        \
82             bus_write_4((_sc)->sc_res, (_r), (_v))
83 #define IOMUX_READ(_sc, _r)                                             \
84             bus_read_4((_sc)->sc_res, (_r))
85 #define IOMUX_SET(_sc, _r, _m)                                          \
86             IOMUX_WRITE((_sc), (_r), IOMUX_READ((_sc), (_r)) | (_m))
87 #define IOMUX_CLEAR(_sc, _r, _m)                                        \
88             IOMUX_WRITE((_sc), (_r), IOMUX_READ((_sc), (_r)) & ~(_m))
89
90 struct iomux_softc {
91         struct resource *sc_res;
92         device_t        sc_dev;
93 };
94
95 static int iomux_probe(device_t);
96 static int iomux_attach(device_t);
97
98 static struct iomux_softc *iomuxsc = NULL;
99
100 static struct resource_spec imx_iomux_spec[] = {
101         { SYS_RES_MEMORY,       0,      RF_ACTIVE },    /* Global registers */
102         { -1, 0 }
103 };
104
105 static int
106 iomux_probe(device_t dev)
107 {
108
109         if (!ofw_bus_status_okay(dev))
110                 return (ENXIO);
111
112         if (!ofw_bus_is_compatible(dev, "fsl,imx51-iomux") &&
113             !ofw_bus_is_compatible(dev, "fsl,imx53-iomux"))
114                 return (ENXIO);
115
116         device_set_desc(dev, "Freescale i.MX51 IO pins multiplexor");
117         return (BUS_PROBE_DEFAULT);
118 }
119
120 static int
121 iomux_attach(device_t dev)
122 {
123         struct iomux_softc * sc;
124
125         sc = device_get_softc(dev);
126
127         if (bus_alloc_resources(dev, imx_iomux_spec, &sc->sc_res)) {
128                 device_printf(dev, "could not allocate resources\n");
129                 return (ENXIO);
130         }
131
132         iomuxsc = sc;
133
134         /*
135          * XXX: place to fetch all info about pinmuxing from loader data
136          * (FDT blob) and apply. Loader (1st one) must care about
137          * device-to-device difference.
138          */
139
140         return (0);
141 }
142
143 static void
144 iomux_set_function_sub(struct iomux_softc *sc, uint32_t pin, uint32_t fn)
145 {
146         bus_size_t mux_ctl_reg = IOMUX_PIN_TO_MUX_ADDRESS(pin);
147
148         if (mux_ctl_reg != IOMUX_MUX_NONE)
149                 IOMUX_WRITE(sc, mux_ctl_reg, fn);
150 }
151
152 void
153 iomux_set_function(unsigned int pin, unsigned int fn)
154 {
155
156         if (iomuxsc == NULL)
157                 return;
158         iomux_set_function_sub(iomuxsc, pin, fn);
159 }
160
161 static void
162 iomux_set_pad_sub(struct iomux_softc *sc, uint32_t pin, uint32_t config)
163 {
164         bus_size_t pad_ctl_reg = IOMUX_PIN_TO_PAD_ADDRESS(pin);
165
166         if (pad_ctl_reg != IOMUX_PAD_NONE)
167                 IOMUX_WRITE(sc, pad_ctl_reg, config);
168 }
169
170 void
171 iomux_set_pad(unsigned int pin, unsigned int config)
172 {
173
174         if (iomuxsc == NULL)
175                 return;
176         iomux_set_pad_sub(iomuxsc, pin, config);
177 }
178
179 #ifdef notyet
180 void
181 iomux_set_input(unsigned int input, unsigned int config)
182 {
183         bus_size_t input_ctl_reg = input;
184
185         bus_space_write_4(iomuxsc->iomux_memt, iomuxsc->iomux_memh,
186             input_ctl_reg, config);
187 }
188 #endif
189
190 void
191 iomux_mux_config(const struct iomux_conf *conflist)
192 {
193         int i;
194
195         if (iomuxsc == NULL)
196                 return;
197         for (i = 0; conflist[i].pin != IOMUX_CONF_EOT; i++) {
198                 iomux_set_pad_sub(iomuxsc, conflist[i].pin, conflist[i].pad);
199                 iomux_set_function_sub(iomuxsc, conflist[i].pin,
200                     conflist[i].mux);
201         }
202 }
203
204 #ifdef notyet
205 void
206 iomux_input_config(const struct iomux_input_conf *conflist)
207 {
208         int i;
209
210         if (iomuxsc == NULL)
211                 return;
212         for (i = 0; conflist[i].inout != -1; i++) {
213                 iomux_set_inout(iomuxsc, conflist[i].inout,
214                     conflist[i].inout_mode);
215         }
216 }
217 #endif
218
219 static device_method_t imx_iomux_methods[] = {
220         DEVMETHOD(device_probe,         iomux_probe),
221         DEVMETHOD(device_attach,        iomux_attach),
222
223         DEVMETHOD_END
224 };
225
226 static driver_t imx_iomux_driver = {
227         "imx_iomux",
228         imx_iomux_methods,
229         sizeof(struct iomux_softc),
230 };
231
232 static devclass_t imx_iomux_devclass;
233
234 EARLY_DRIVER_MODULE(imx_iomux, simplebus, imx_iomux_driver,
235     imx_iomux_devclass, 0, 0, BUS_PASS_BUS - 1);
236