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