imx51_iomux.c revision 1.1 1 /* $NetBSD: imx51_iomux.c,v 1.1 2010/11/30 13:05:27 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 #include <sys/cdefs.h>
29 __KERNEL_RCSID(0, "$NetBSD: imx51_iomux.c,v 1.1 2010/11/30 13:05:27 bsh Exp $");
30
31 #define _INTR_PRIVATE
32
33 #include "locators.h"
34
35 #include <sys/param.h>
36 #include <sys/evcnt.h>
37 #include <sys/atomic.h>
38 #include <sys/device.h>
39
40 #include <uvm/uvm_extern.h>
41
42 #include <machine/intr.h>
43
44 #include <arm/cpu.h>
45 #include <arm/armreg.h>
46 #include <arm/cpufunc.h>
47
48 #include <machine/bus.h>
49
50 #include <arm/imx/imx51reg.h>
51 #include <arm/imx/imx51var.h>
52
53 struct iomux_softc {
54 struct device iomux_dev;
55 bus_space_tag_t iomux_memt;
56 bus_space_handle_t iomux_memh;
57 };
58
59 extern struct cfdriver imxiomux_cd;
60
61 #define IOMUX_READ(iomux, reg) \
62 bus_space_read_4((iomux)->iomux_memt, (iomux)->iomux_memh, (reg))
63 #define IOMUX_WRITE(iomux, reg, val) \
64 bus_space_write_4((iomux)->iomux_memt, (iomux)->iomux_memh, (reg), (val))
65
66 static int iomux_match(device_t, cfdata_t, void *);
67 static void iomux_attach(device_t, device_t, void *);
68
69 static struct iomux_softc *iomuxsc = NULL;
70
71 CFATTACH_DECL(imxiomux,
72 sizeof(struct iomux_softc),
73 iomux_match, iomux_attach,
74 NULL, NULL);
75
76 int
77 iomux_match(device_t parent, cfdata_t cfdata, void *aux)
78 {
79 struct axi_attach_args *axia = aux;
80
81 if (axia->aa_addr != IOMUXC_BASE)
82 return 0;
83
84 return 1;
85 }
86
87 void
88 iomux_attach(device_t parent, device_t self, void *aux)
89 {
90 struct axi_attach_args * const axia = aux;
91 struct iomux_softc * const iomux = device_private(self);
92 int error;
93
94 if (axia->aa_size == AXICF_SIZE_DEFAULT)
95 axia->aa_size = IOMUXC_SIZE;
96
97 iomux->iomux_memt = axia->aa_iot;
98 error = bus_space_map(axia->aa_iot, axia->aa_addr, axia->aa_size,
99 0, &iomux->iomux_memh);
100
101 if (error) {
102 aprint_error(": failed to map register %#lx@%#lx: %d\n",
103 axia->aa_size, axia->aa_addr, error);
104 return;
105 }
106
107 aprint_normal("\n");
108
109 iomuxsc = iomux;
110 }
111
112 static void
113 iomux_set_function_sub(struct iomux_softc *sc, uint32_t pin, uint32_t fn)
114 {
115 bus_size_t mux_ctl_reg = IOMUX_PIN_TO_MUX_ADDRESS(pin);
116
117 if (mux_ctl_reg != IOMUX_MUX_NONE)
118 bus_space_write_4(sc->iomux_memt, sc->iomux_memh,
119 mux_ctl_reg, fn);
120 }
121
122 void
123 iomux_set_function(unsigned int pin, unsigned int fn)
124 {
125 iomux_set_function_sub(iomuxsc, pin, fn);
126 }
127
128
129 static void
130 iomux_set_pad_sub(struct iomux_softc *sc, uint32_t pin, uint32_t config)
131 {
132 bus_size_t pad_ctl_reg = IOMUX_PIN_TO_PAD_ADDRESS(pin);
133
134 if (pad_ctl_reg != IOMUX_PAD_NONE)
135 bus_space_write_4(sc->iomux_memt, sc->iomux_memh,
136 pad_ctl_reg, config);
137 }
138
139 void
140 iomux_set_pad(unsigned int pin, unsigned int config)
141 {
142 iomux_set_pad_sub(iomuxsc, pin, config);
143 }
144
145 #if 0
146 void
147 iomux_set_input(unsigned int input, unsigned int config)
148 {
149 bus_size_t input_ctl_reg = input;
150
151 bus_space_write_4(iomuxsc->iomux_memt, iomuxsc->iomux_memh,
152 input_ctl_reg, config);
153 }
154 #endif
155
156 void
157 iomux_mux_config(const struct iomux_conf *conflist)
158 {
159 int i;
160
161 for (i = 0; conflist[i].pin != IOMUX_CONF_EOT; i++) {
162 iomux_set_pad_sub(iomuxsc, conflist[i].pin, conflist[i].pad);
163 iomux_set_function_sub(iomuxsc, conflist[i].pin,
164 conflist[i].mux);
165 }
166 }
167
168 #if 0
169 void
170 iomux_input_config(const struct iomux_input_conf *conflist)
171 {
172 int i;
173
174 for (i = 0; conflist[i].inout != -1; i++) {
175 iomux_set_inout(iomuxsc, conflist[i].inout,
176 conflist[i].inout_mode);
177 }
178 }
179 #endif
180
181