]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - sys/arm/freescale/imx/imx51_iomux.c
Copy head (r256279) to stable/10 as part of the 10.0-RELEASE cycle.
[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_is_compatible(dev, "fsl,imx51-iomux") &&
110             !ofw_bus_is_compatible(dev, "fsl,imx53-iomux"))
111                 return (ENXIO);
112
113         device_set_desc(dev, "Freescale i.MX51 IO pins multiplexor");
114         return (BUS_PROBE_DEFAULT);
115 }
116
117 static int
118 iomux_attach(device_t dev)
119 {
120         struct iomux_softc * sc;
121
122         sc = device_get_softc(dev);
123
124         if (bus_alloc_resources(dev, imx_iomux_spec, &sc->sc_res)) {
125                 device_printf(dev, "could not allocate resources\n");
126                 return (ENXIO);
127         }
128
129         iomuxsc = sc;
130
131         /*
132          * XXX: place to fetch all info about pinmuxing from loader data
133          * (FDT blob) and apply. Loader (1st one) must care about
134          * device-to-device difference.
135          */
136
137         return (0);
138 }
139
140 static void
141 iomux_set_function_sub(struct iomux_softc *sc, uint32_t pin, uint32_t fn)
142 {
143         bus_size_t mux_ctl_reg = IOMUX_PIN_TO_MUX_ADDRESS(pin);
144
145         if (mux_ctl_reg != IOMUX_MUX_NONE)
146                 IOMUX_WRITE(sc, mux_ctl_reg, fn);
147 }
148
149 void
150 iomux_set_function(unsigned int pin, unsigned int fn)
151 {
152
153         if (iomuxsc == NULL)
154                 return;
155         iomux_set_function_sub(iomuxsc, pin, fn);
156 }
157
158 static void
159 iomux_set_pad_sub(struct iomux_softc *sc, uint32_t pin, uint32_t config)
160 {
161         bus_size_t pad_ctl_reg = IOMUX_PIN_TO_PAD_ADDRESS(pin);
162
163         if (pad_ctl_reg != IOMUX_PAD_NONE)
164                 IOMUX_WRITE(sc, pad_ctl_reg, config);
165 }
166
167 void
168 iomux_set_pad(unsigned int pin, unsigned int config)
169 {
170
171         if (iomuxsc == NULL)
172                 return;
173         iomux_set_pad_sub(iomuxsc, pin, config);
174 }
175
176 #ifdef notyet
177 void
178 iomux_set_input(unsigned int input, unsigned int config)
179 {
180         bus_size_t input_ctl_reg = input;
181
182         bus_space_write_4(iomuxsc->iomux_memt, iomuxsc->iomux_memh,
183             input_ctl_reg, config);
184 }
185 #endif
186
187 void
188 iomux_mux_config(const struct iomux_conf *conflist)
189 {
190         int i;
191
192         if (iomuxsc == NULL)
193                 return;
194         for (i = 0; conflist[i].pin != IOMUX_CONF_EOT; i++) {
195                 iomux_set_pad_sub(iomuxsc, conflist[i].pin, conflist[i].pad);
196                 iomux_set_function_sub(iomuxsc, conflist[i].pin,
197                     conflist[i].mux);
198         }
199 }
200
201 #ifdef notyet
202 void
203 iomux_input_config(const struct iomux_input_conf *conflist)
204 {
205         int i;
206
207         if (iomuxsc == NULL)
208                 return;
209         for (i = 0; conflist[i].inout != -1; i++) {
210                 iomux_set_inout(iomuxsc, conflist[i].inout,
211                     conflist[i].inout_mode);
212         }
213 }
214 #endif
215
216 static device_method_t imx_iomux_methods[] = {
217         DEVMETHOD(device_probe,         iomux_probe),
218         DEVMETHOD(device_attach,        iomux_attach),
219
220         DEVMETHOD_END
221 };
222
223 static driver_t imx_iomux_driver = {
224         "imx_iomux",
225         imx_iomux_methods,
226         sizeof(struct iomux_softc),
227 };
228
229 static devclass_t imx_iomux_devclass;
230
231 EARLY_DRIVER_MODULE(imx_iomux, simplebus, imx_iomux_driver,
232     imx_iomux_devclass, 0, 0, BUS_PASS_BUS - 1);
233