imx51_iomux.c revision 1.2 1 1.2 dyoung /* $NetBSD: imx51_iomux.c,v 1.2 2011/07/01 20:27:50 dyoung Exp $ */
2 1.1 bsh
3 1.1 bsh /*
4 1.1 bsh * Copyright (c) 2009, 2010 Genetec Corporation. All rights reserved.
5 1.1 bsh * Written by Hashimoto Kenichi for Genetec Corporation.
6 1.1 bsh *
7 1.1 bsh * Redistribution and use in source and binary forms, with or without
8 1.1 bsh * modification, are permitted provided that the following conditions
9 1.1 bsh * are met:
10 1.1 bsh * 1. Redistributions of source code must retain the above copyright
11 1.1 bsh * notice, this list of conditions and the following disclaimer.
12 1.1 bsh * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 bsh * notice, this list of conditions and the following disclaimer in the
14 1.1 bsh * documentation and/or other materials provided with the distribution.
15 1.1 bsh *
16 1.1 bsh * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
17 1.1 bsh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 1.1 bsh * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 1.1 bsh * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION
20 1.1 bsh * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 1.1 bsh * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 1.1 bsh * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 1.1 bsh * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 1.1 bsh * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 1.1 bsh * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 1.1 bsh * POSSIBILITY OF SUCH DAMAGE.
27 1.1 bsh */
28 1.1 bsh #include <sys/cdefs.h>
29 1.2 dyoung __KERNEL_RCSID(0, "$NetBSD: imx51_iomux.c,v 1.2 2011/07/01 20:27:50 dyoung Exp $");
30 1.1 bsh
31 1.1 bsh #define _INTR_PRIVATE
32 1.1 bsh
33 1.1 bsh #include "locators.h"
34 1.1 bsh
35 1.1 bsh #include <sys/param.h>
36 1.1 bsh #include <sys/evcnt.h>
37 1.1 bsh #include <sys/atomic.h>
38 1.1 bsh #include <sys/device.h>
39 1.1 bsh
40 1.1 bsh #include <uvm/uvm_extern.h>
41 1.1 bsh
42 1.1 bsh #include <machine/intr.h>
43 1.1 bsh
44 1.1 bsh #include <arm/cpu.h>
45 1.1 bsh #include <arm/armreg.h>
46 1.1 bsh #include <arm/cpufunc.h>
47 1.1 bsh
48 1.2 dyoung #include <sys/bus.h>
49 1.1 bsh
50 1.1 bsh #include <arm/imx/imx51reg.h>
51 1.1 bsh #include <arm/imx/imx51var.h>
52 1.1 bsh
53 1.1 bsh struct iomux_softc {
54 1.1 bsh struct device iomux_dev;
55 1.1 bsh bus_space_tag_t iomux_memt;
56 1.1 bsh bus_space_handle_t iomux_memh;
57 1.1 bsh };
58 1.1 bsh
59 1.1 bsh extern struct cfdriver imxiomux_cd;
60 1.1 bsh
61 1.1 bsh #define IOMUX_READ(iomux, reg) \
62 1.1 bsh bus_space_read_4((iomux)->iomux_memt, (iomux)->iomux_memh, (reg))
63 1.1 bsh #define IOMUX_WRITE(iomux, reg, val) \
64 1.1 bsh bus_space_write_4((iomux)->iomux_memt, (iomux)->iomux_memh, (reg), (val))
65 1.1 bsh
66 1.1 bsh static int iomux_match(device_t, cfdata_t, void *);
67 1.1 bsh static void iomux_attach(device_t, device_t, void *);
68 1.1 bsh
69 1.1 bsh static struct iomux_softc *iomuxsc = NULL;
70 1.1 bsh
71 1.1 bsh CFATTACH_DECL(imxiomux,
72 1.1 bsh sizeof(struct iomux_softc),
73 1.1 bsh iomux_match, iomux_attach,
74 1.1 bsh NULL, NULL);
75 1.1 bsh
76 1.1 bsh int
77 1.1 bsh iomux_match(device_t parent, cfdata_t cfdata, void *aux)
78 1.1 bsh {
79 1.1 bsh struct axi_attach_args *axia = aux;
80 1.1 bsh
81 1.1 bsh if (axia->aa_addr != IOMUXC_BASE)
82 1.1 bsh return 0;
83 1.1 bsh
84 1.1 bsh return 1;
85 1.1 bsh }
86 1.1 bsh
87 1.1 bsh void
88 1.1 bsh iomux_attach(device_t parent, device_t self, void *aux)
89 1.1 bsh {
90 1.1 bsh struct axi_attach_args * const axia = aux;
91 1.1 bsh struct iomux_softc * const iomux = device_private(self);
92 1.1 bsh int error;
93 1.1 bsh
94 1.1 bsh if (axia->aa_size == AXICF_SIZE_DEFAULT)
95 1.1 bsh axia->aa_size = IOMUXC_SIZE;
96 1.1 bsh
97 1.1 bsh iomux->iomux_memt = axia->aa_iot;
98 1.1 bsh error = bus_space_map(axia->aa_iot, axia->aa_addr, axia->aa_size,
99 1.1 bsh 0, &iomux->iomux_memh);
100 1.1 bsh
101 1.1 bsh if (error) {
102 1.1 bsh aprint_error(": failed to map register %#lx@%#lx: %d\n",
103 1.1 bsh axia->aa_size, axia->aa_addr, error);
104 1.1 bsh return;
105 1.1 bsh }
106 1.1 bsh
107 1.1 bsh aprint_normal("\n");
108 1.1 bsh
109 1.1 bsh iomuxsc = iomux;
110 1.1 bsh }
111 1.1 bsh
112 1.1 bsh static void
113 1.1 bsh iomux_set_function_sub(struct iomux_softc *sc, uint32_t pin, uint32_t fn)
114 1.1 bsh {
115 1.1 bsh bus_size_t mux_ctl_reg = IOMUX_PIN_TO_MUX_ADDRESS(pin);
116 1.1 bsh
117 1.1 bsh if (mux_ctl_reg != IOMUX_MUX_NONE)
118 1.1 bsh bus_space_write_4(sc->iomux_memt, sc->iomux_memh,
119 1.1 bsh mux_ctl_reg, fn);
120 1.1 bsh }
121 1.1 bsh
122 1.1 bsh void
123 1.1 bsh iomux_set_function(unsigned int pin, unsigned int fn)
124 1.1 bsh {
125 1.1 bsh iomux_set_function_sub(iomuxsc, pin, fn);
126 1.1 bsh }
127 1.1 bsh
128 1.1 bsh
129 1.1 bsh static void
130 1.1 bsh iomux_set_pad_sub(struct iomux_softc *sc, uint32_t pin, uint32_t config)
131 1.1 bsh {
132 1.1 bsh bus_size_t pad_ctl_reg = IOMUX_PIN_TO_PAD_ADDRESS(pin);
133 1.1 bsh
134 1.1 bsh if (pad_ctl_reg != IOMUX_PAD_NONE)
135 1.1 bsh bus_space_write_4(sc->iomux_memt, sc->iomux_memh,
136 1.1 bsh pad_ctl_reg, config);
137 1.1 bsh }
138 1.1 bsh
139 1.1 bsh void
140 1.1 bsh iomux_set_pad(unsigned int pin, unsigned int config)
141 1.1 bsh {
142 1.1 bsh iomux_set_pad_sub(iomuxsc, pin, config);
143 1.1 bsh }
144 1.1 bsh
145 1.1 bsh #if 0
146 1.1 bsh void
147 1.1 bsh iomux_set_input(unsigned int input, unsigned int config)
148 1.1 bsh {
149 1.1 bsh bus_size_t input_ctl_reg = input;
150 1.1 bsh
151 1.1 bsh bus_space_write_4(iomuxsc->iomux_memt, iomuxsc->iomux_memh,
152 1.1 bsh input_ctl_reg, config);
153 1.1 bsh }
154 1.1 bsh #endif
155 1.1 bsh
156 1.1 bsh void
157 1.1 bsh iomux_mux_config(const struct iomux_conf *conflist)
158 1.1 bsh {
159 1.1 bsh int i;
160 1.1 bsh
161 1.1 bsh for (i = 0; conflist[i].pin != IOMUX_CONF_EOT; i++) {
162 1.1 bsh iomux_set_pad_sub(iomuxsc, conflist[i].pin, conflist[i].pad);
163 1.1 bsh iomux_set_function_sub(iomuxsc, conflist[i].pin,
164 1.1 bsh conflist[i].mux);
165 1.1 bsh }
166 1.1 bsh }
167 1.1 bsh
168 1.1 bsh #if 0
169 1.1 bsh void
170 1.1 bsh iomux_input_config(const struct iomux_input_conf *conflist)
171 1.1 bsh {
172 1.1 bsh int i;
173 1.1 bsh
174 1.1 bsh for (i = 0; conflist[i].inout != -1; i++) {
175 1.1 bsh iomux_set_inout(iomuxsc, conflist[i].inout,
176 1.1 bsh conflist[i].inout_mode);
177 1.1 bsh }
178 1.1 bsh }
179 1.1 bsh #endif
180 1.1 bsh
181