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