xref: /netbsd-src/sys/arch/arm/imx/imx23_pinctrl.c (revision c7fb772b85b2b5d4cfb282f868f454b4701534fd)
1*c7fb772bSthorpej /* $Id: imx23_pinctrl.c,v 1.6 2021/08/07 16:18:44 thorpej Exp $ */
294de0730Smatt 
394de0730Smatt /*
494de0730Smatt * Copyright (c) 2013 The NetBSD Foundation, Inc.
594de0730Smatt * All rights reserved.
694de0730Smatt *
794de0730Smatt * This code is derived from software contributed to The NetBSD Foundation
894de0730Smatt * by Petri Laakso.
994de0730Smatt *
1094de0730Smatt * Redistribution and use in source and binary forms, with or without
1194de0730Smatt * modification, are permitted provided that the following conditions
1294de0730Smatt * are met:
1394de0730Smatt * 1. Redistributions of source code must retain the above copyright
1494de0730Smatt *    notice, this list of conditions and the following disclaimer.
1594de0730Smatt * 2. Redistributions in binary form must reproduce the above copyright
1694de0730Smatt *    notice, this list of conditions and the following disclaimer in the
1794de0730Smatt *    documentation and/or other materials provided with the distribution.
1894de0730Smatt *
1994de0730Smatt * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2094de0730Smatt * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2194de0730Smatt * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2294de0730Smatt * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2394de0730Smatt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2494de0730Smatt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2594de0730Smatt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2694de0730Smatt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2794de0730Smatt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2894de0730Smatt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2994de0730Smatt * POSSIBILITY OF SUCH DAMAGE.
3094de0730Smatt */
3194de0730Smatt 
3294de0730Smatt #include <sys/param.h>
3394de0730Smatt #include <sys/types.h>
3494de0730Smatt #include <sys/bus.h>
3594de0730Smatt #include <sys/cdefs.h>
3694de0730Smatt #include <sys/device.h>
3794de0730Smatt #include <sys/errno.h>
3894de0730Smatt #include <sys/gpio.h>
3994de0730Smatt 
4094de0730Smatt #include <dev/gpio/gpiovar.h>
4194de0730Smatt 
4294de0730Smatt #include <arm/imx/imx23_pinctrlreg.h>
4394de0730Smatt #include <arm/imx/imx23_pinctrlvar.h>
4494de0730Smatt #include <arm/imx/imx23var.h>
4594de0730Smatt 
4694de0730Smatt #define GPIO_PINS 96
4794de0730Smatt 
4868bc6eb1Sskrll typedef struct imx23_pinctrl_softc {
4994de0730Smatt 	device_t sc_dev;
5094de0730Smatt 	bus_space_tag_t sc_iot;
5194de0730Smatt 	bus_space_handle_t sc_hdl;
5294de0730Smatt 	struct gpio_chipset_tag gc;
5394de0730Smatt 	gpio_pin_t pins[GPIO_PINS];
5468bc6eb1Sskrll } *imx23_pinctrl_softc_t;
5594de0730Smatt 
5668bc6eb1Sskrll static int	imx23_pinctrl_match(device_t, cfdata_t, void *);
5768bc6eb1Sskrll static void	imx23_pinctrl_attach(device_t, device_t, void *);
5868bc6eb1Sskrll static int	imx23_pinctrl_activate(device_t, enum devact);
5994de0730Smatt 
6094de0730Smatt #if notyet
6168bc6eb1Sskrll static void     imx23_pinctrl_reset(struct imx23_pinctrl_softc *);
6294de0730Smatt #endif
6368bc6eb1Sskrll static void     imx23_pinctrl_init(struct imx23_pinctrl_softc *);
6494de0730Smatt 
6568bc6eb1Sskrll static	int	imx23_pinctrl_gp_gc_open(void *, device_t);
6668bc6eb1Sskrll static	void	imx23_pinctrl_gp_gc_close(void *, device_t);
6768bc6eb1Sskrll static	int	imx23_pinctrl_gp_pin_read(void *, int);
6868bc6eb1Sskrll static	void	imx23_pinctrl_gp_pin_write(void *, int, int);
6968bc6eb1Sskrll static	void	imx23_pinctrl_gp_pin_ctl(void *, int, int);
7094de0730Smatt 
7168bc6eb1Sskrll static imx23_pinctrl_softc_t _sc = NULL;
7294de0730Smatt 
7368bc6eb1Sskrll CFATTACH_DECL3_NEW(imx23_pinctrl,
7468bc6eb1Sskrll         sizeof(struct imx23_pinctrl_softc),
7568bc6eb1Sskrll         imx23_pinctrl_match,
7668bc6eb1Sskrll         imx23_pinctrl_attach,
7794de0730Smatt         NULL,
7868bc6eb1Sskrll         imx23_pinctrl_activate,
7994de0730Smatt         NULL,
8094de0730Smatt         NULL,
8194de0730Smatt         0
8294de0730Smatt );
8394de0730Smatt 
8494de0730Smatt #define GPIO_PIN_CAP (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_INOUT | \
8594de0730Smatt 		GPIO_PIN_PULLUP | GPIO_PIN_SET)
8694de0730Smatt 
8794de0730Smatt /*
8894de0730Smatt  * Supported capabilities for each GPIO pin.
8994de0730Smatt  */
9094de0730Smatt const static int pin_caps[GPIO_PINS] = {
9194de0730Smatt 	/*
9294de0730Smatt 	 * HW_PINCTRL_MUXSEL0
9394de0730Smatt 	 */
9494de0730Smatt 	/* PIN 0 */
9594de0730Smatt 	GPIO_PIN_CAP,
9694de0730Smatt 	/* PIN 1 */
9794de0730Smatt 	GPIO_PIN_CAP,
9894de0730Smatt 	/* PIN 2 */
9994de0730Smatt 	GPIO_PIN_CAP,
10094de0730Smatt 	/* PIN 3 */
10194de0730Smatt 	GPIO_PIN_CAP,
10294de0730Smatt 	/* PIN 4 */
10394de0730Smatt 	GPIO_PIN_CAP,
10494de0730Smatt 	/* PIN 5 */
10594de0730Smatt 	GPIO_PIN_CAP,
10694de0730Smatt 	/* PIN 6 */
10794de0730Smatt 	GPIO_PIN_CAP,
10894de0730Smatt 	/* PIN 7 */
10994de0730Smatt 	GPIO_PIN_CAP,
11094de0730Smatt 	/* PIN 8 */
11194de0730Smatt 	GPIO_PIN_CAP,
11294de0730Smatt 	/* PIN 9 */
11394de0730Smatt 	GPIO_PIN_CAP,
11494de0730Smatt 	/* PIN 10 */
11594de0730Smatt 	GPIO_PIN_CAP,
11694de0730Smatt 	/* PIN 11 */
11794de0730Smatt 	GPIO_PIN_CAP,
11894de0730Smatt 	/* PIN 12 */
11994de0730Smatt 	GPIO_PIN_CAP,
12094de0730Smatt 	/* PIN 13 */
12194de0730Smatt 	GPIO_PIN_CAP,
12294de0730Smatt 	/* PIN 14 */
12394de0730Smatt 	GPIO_PIN_CAP,
12494de0730Smatt 	/* PIN 15 */
12594de0730Smatt 	GPIO_PIN_CAP,
12694de0730Smatt 	/*
12794de0730Smatt 	 * HW_PINCTRL_MUXSEL1
12894de0730Smatt 	 */
12994de0730Smatt 	/* PIN 16 */
13094de0730Smatt 	GPIO_PIN_CAP,
13194de0730Smatt 	/* PIN 17 */
13294de0730Smatt 	0,		/* Reserved for powering OLinuXino MAXI/MINI USB hub. */
13394de0730Smatt 	/* PIN 18 */
13494de0730Smatt 	GPIO_PIN_CAP,
13594de0730Smatt 	/* PIN 19 */
13694de0730Smatt 	GPIO_PIN_CAP,
13794de0730Smatt 	/* PIN 20 */
13894de0730Smatt 	GPIO_PIN_CAP,
13994de0730Smatt 	/* PIN 21 */
14094de0730Smatt 	GPIO_PIN_CAP,
14194de0730Smatt 	/* PIN 22 */
14294de0730Smatt 	GPIO_PIN_CAP,
14394de0730Smatt 	/* PIN 23 */
14494de0730Smatt 	GPIO_PIN_CAP,
14594de0730Smatt 	/* PIN 24 */
14694de0730Smatt 	GPIO_PIN_CAP,
14794de0730Smatt 	/* PIN 25 */
14894de0730Smatt 	GPIO_PIN_CAP,
14994de0730Smatt 	/* PIN 26 */
15094de0730Smatt 	GPIO_PIN_CAP,
15194de0730Smatt 	/* PIN 27 */
15294de0730Smatt 	GPIO_PIN_CAP,
15394de0730Smatt 	/* PIN 28 */
15494de0730Smatt 	GPIO_PIN_CAP,
15594de0730Smatt 	/* PIN 29 */
15694de0730Smatt 	GPIO_PIN_CAP,
15794de0730Smatt 	/* PIN 30 */
15894de0730Smatt 	GPIO_PIN_CAP,
15994de0730Smatt 	/* PIN 31 */
16094de0730Smatt 	GPIO_PIN_CAP,
16194de0730Smatt 	/*
16294de0730Smatt 	 * HW_PINCTRL_MUXSEL2
16394de0730Smatt 	 */
16494de0730Smatt 	/* PIN 32 */
16594de0730Smatt 	GPIO_PIN_CAP,
16694de0730Smatt 	/* PIN 33 */
16794de0730Smatt 	GPIO_PIN_CAP,
16894de0730Smatt 	/* PIN 34 */
16994de0730Smatt 	GPIO_PIN_CAP,
17094de0730Smatt 	/* PIN 35 */
17194de0730Smatt 	GPIO_PIN_CAP,
17294de0730Smatt 	/* PIN 36 */
17394de0730Smatt 	GPIO_PIN_CAP,
17494de0730Smatt 	/* PIN 37 */
17594de0730Smatt 	GPIO_PIN_CAP,
17694de0730Smatt 	/* PIN 38 */
17794de0730Smatt 	GPIO_PIN_CAP,
17894de0730Smatt 	/* PIN 39 */
17994de0730Smatt 	GPIO_PIN_CAP,
18094de0730Smatt 	/* PIN 40 */
18194de0730Smatt 	GPIO_PIN_CAP,
18294de0730Smatt 	/* PIN 41 */
18394de0730Smatt 	GPIO_PIN_CAP,
18494de0730Smatt 	/* PIN 42 */
18594de0730Smatt 	GPIO_PIN_CAP,
18694de0730Smatt 	/* PIN 43 */
18794de0730Smatt 	GPIO_PIN_CAP,
18894de0730Smatt 	/* PIN 44 */
18994de0730Smatt 	GPIO_PIN_CAP,
19094de0730Smatt 	/* PIN 45 */
19194de0730Smatt 	GPIO_PIN_CAP,
19294de0730Smatt 	/* PIN 46 */
19394de0730Smatt 	GPIO_PIN_CAP,
19494de0730Smatt 	/* PIN 47 */
19594de0730Smatt 	GPIO_PIN_CAP,
19694de0730Smatt 	/*
19794de0730Smatt 	 * HW_PINCTRL_MUXSEL3
19894de0730Smatt 	 */
19994de0730Smatt 	/* PIN 48 */
20094de0730Smatt 	GPIO_PIN_CAP,
20194de0730Smatt 	/* PIN 49 */
20294de0730Smatt 	GPIO_PIN_CAP,
20394de0730Smatt 	/* PIN 50 */
20494de0730Smatt 	GPIO_PIN_CAP,
20594de0730Smatt 	/* PIN 51 */
20694de0730Smatt 	GPIO_PIN_CAP,
20794de0730Smatt 	/* PIN 52 */
20894de0730Smatt 	GPIO_PIN_CAP,
20994de0730Smatt 	/* PIN 53 */
21094de0730Smatt 	GPIO_PIN_CAP,
21194de0730Smatt 	/* PIN 54 */
21294de0730Smatt 	GPIO_PIN_CAP,
21394de0730Smatt 	/* PIN 55 */
21494de0730Smatt 	GPIO_PIN_CAP,
21594de0730Smatt 	/* PIN 56 */
21694de0730Smatt 	GPIO_PIN_CAP,
21794de0730Smatt 	/* PIN 57 */
21894de0730Smatt 	GPIO_PIN_CAP,
21994de0730Smatt 	/* PIN 58 */
22094de0730Smatt 	GPIO_PIN_CAP,
22194de0730Smatt 	/* PIN 59 */
22294de0730Smatt 	GPIO_PIN_CAP,
22394de0730Smatt 	/* PIN 60 */
22494de0730Smatt 	GPIO_PIN_CAP,
22594de0730Smatt 	/* PIN 61 */
22694de0730Smatt 	GPIO_PIN_CAP,
22794de0730Smatt 	/* PIN 62 */
22894de0730Smatt 	GPIO_PIN_CAP,
22994de0730Smatt 	/* PIN 63 */
23094de0730Smatt 	0,		/* Reserved. */
23194de0730Smatt 	/*
23294de0730Smatt 	 * HW_PINCTRL_MUXSEL4
23394de0730Smatt 	 */
23494de0730Smatt 	/* PIN 64 */
23594de0730Smatt 	GPIO_PIN_CAP,
23694de0730Smatt 	/* PIN 65 */
23794de0730Smatt 	GPIO_PIN_CAP,
23894de0730Smatt 	/* PIN 66 */
23994de0730Smatt 	GPIO_PIN_CAP,
24094de0730Smatt 	/* PIN 67 */
24194de0730Smatt 	GPIO_PIN_CAP,
24294de0730Smatt 	/* PIN 68 */
24394de0730Smatt 	GPIO_PIN_CAP,
24494de0730Smatt 	/* PIN 69 */
24594de0730Smatt 	GPIO_PIN_CAP,
24694de0730Smatt 	/* PIN 70 */
24794de0730Smatt 	GPIO_PIN_CAP,
24894de0730Smatt 	/* PIN 71 */
24994de0730Smatt 	GPIO_PIN_CAP,
25094de0730Smatt 	/* PIN 72 */
25194de0730Smatt 	GPIO_PIN_CAP,
25294de0730Smatt 	/* PIN 73 */
25394de0730Smatt 	0,		/* From this on reserved for EMI (DRAM) pins. */
25494de0730Smatt 	/* PIN 74 */
25594de0730Smatt 	0,
25694de0730Smatt 	/* PIN 75 */
25794de0730Smatt 	0,
25894de0730Smatt 	/* PIN 76 */
25994de0730Smatt 	0,
26094de0730Smatt 	/* PIN 77 */
26194de0730Smatt 	0,
26294de0730Smatt 	/* PIN 78 */
26394de0730Smatt 	0,
26494de0730Smatt 	/* PIN 79 */
26594de0730Smatt 	0,
26694de0730Smatt 	/*
26794de0730Smatt 	 * HW_PINCTRL_MUXSEL5
26894de0730Smatt 	 */
26994de0730Smatt 	/* PIN 80 */
27094de0730Smatt 	0,
27194de0730Smatt 	/* PIN 81 */
27294de0730Smatt 	0,
27394de0730Smatt 	/* PIN 82 */
27494de0730Smatt 	0,
27594de0730Smatt 	/* PIN 83 */
27694de0730Smatt 	0,
27794de0730Smatt 	/* PIN 84 */
27894de0730Smatt 	0,
27994de0730Smatt 	/* PIN 85 */
28094de0730Smatt 	0,
28194de0730Smatt 	/* PIN 86 */
28294de0730Smatt 	0,
28394de0730Smatt 	/* PIN 87 */
28494de0730Smatt 	0,
28594de0730Smatt 	/* PIN 88 */
28694de0730Smatt 	0,
28794de0730Smatt 	/* PIN 89 */
28894de0730Smatt 	0,
28994de0730Smatt 	/* PIN 90 */
29094de0730Smatt 	0,
29194de0730Smatt 	/* PIN 91 */
29294de0730Smatt 	0,
29394de0730Smatt 	/* PIN 92 */
29494de0730Smatt 	0,
29594de0730Smatt 	/* PIN 93 */
29694de0730Smatt 	0,
29794de0730Smatt 	/* PIN 94 */
29894de0730Smatt 	0,
29994de0730Smatt 	/* PIN 95 */
30094de0730Smatt 	0
30194de0730Smatt };
30294de0730Smatt 
30394de0730Smatt #define PINCTRL_RD(sc, reg)						\
30494de0730Smatt 	bus_space_read_4(sc->sc_iot, sc->sc_hdl, (reg))
30594de0730Smatt #define PINCTRL_WR(sc, reg, val)					\
30694de0730Smatt 	bus_space_write_4(sc->sc_iot, sc->sc_hdl, (reg), (val))
30794de0730Smatt 
30894de0730Smatt /*
30994de0730Smatt  * Macros to map pin numbers to registers and bit fields.
31094de0730Smatt  */
31194de0730Smatt #define MUXSEL_REG_SIZE	0x10
31294de0730Smatt #define PIN2MUXSEL_REG(pin)						\
31394de0730Smatt 	((pin / 16) * MUXSEL_REG_SIZE + HW_PINCTRL_MUXSEL0)
31494de0730Smatt #define PIN2MUXSEL_SET_REG(pin)						\
31594de0730Smatt 	((pin / 16) * MUXSEL_REG_SIZE + HW_PINCTRL_MUXSEL0_SET)
31694de0730Smatt #define PIN2MUXSEL_CLR_REG(pin)						\
31794de0730Smatt 	((pin / 16) * MUXSEL_REG_SIZE + HW_PINCTRL_MUXSEL0_CLR)
31894de0730Smatt #define PIN2MUXSEL_MASK(pin)	(3<<(pin % 16 * 2))
31994de0730Smatt 
32094de0730Smatt #define DRIVE_REG_SIZE	0x10
32194de0730Smatt #define PIN2DRIVE_REG(pin)						\
32294de0730Smatt 	((pin / 8) * DRIVE_REG_SIZE + HW_PINCTRL_DRIVE0)
32394de0730Smatt #define PIN2DRIVE_SET_REG(pin)						\
32494de0730Smatt 	((pin / 8) * DRIVE_REG_SIZE + HW_PINCTRL_DRIVE0_SET)
32594de0730Smatt #define PIN2DRIVE_CLR_REG(pin)						\
32694de0730Smatt 	((pin / 8) * DRIVE_REG_SIZE + HW_PINCTRL_DRIVE0_CLR)
32794de0730Smatt #define PIN2DRIVE_MASK(pin)	(3<<(pin % 8 * 4))
32894de0730Smatt 
32994de0730Smatt #define PULL_REG_SIZE	0x10
33094de0730Smatt #define PIN2PULL_REG(pin)						\
33194de0730Smatt 	((pin / 32) * PULL_REG_SIZE + HW_PINCTRL_PULL0)
33294de0730Smatt #define PIN2PULL_SET_REG(pin)						\
33394de0730Smatt 	((pin / 32) * PULL_REG_SIZE + HW_PINCTRL_PULL0_SET)
33494de0730Smatt #define PIN2PULL_CLR_REG(pin)						\
33594de0730Smatt 	((pin / 32) * PULL_REG_SIZE + HW_PINCTRL_PULL0_CLR)
33694de0730Smatt #define PIN2PULL_MASK(pin)	(1<<(pin % 32))
33794de0730Smatt 
33894de0730Smatt #define DOUT_REG_SIZE	0x10
33994de0730Smatt #define PIN2DOUT_REG(pin)						\
34094de0730Smatt 	((pin / 32) * DOUT_REG_SIZE + HW_PINCTRL_DOUT0)
34194de0730Smatt #define PIN2DOUT_SET_REG(pin)						\
34294de0730Smatt 	((pin / 32) * DOUT_REG_SIZE + HW_PINCTRL_DOUT0_SET)
34394de0730Smatt #define PIN2DOUT_CLR_REG(pin)						\
34494de0730Smatt 	((pin / 32) * DOUT_REG_SIZE + HW_PINCTRL_DOUT0_CLR)
34594de0730Smatt #define PIN2DOUT_MASK(pin)	(1<<(pin % 32))
34694de0730Smatt 
34794de0730Smatt #define DIN_REG_SIZE	0x10
34894de0730Smatt #define PIN2DIN_REG(pin)	((pin / 32) * DIN_REG_SIZE + HW_PINCTRL_DIN0)
34994de0730Smatt #define PIN2DIN_MASK(pin)	(1<<(pin % 32))
35094de0730Smatt 
35194de0730Smatt #define DOE_REG_SIZE	0x10
35294de0730Smatt #define PIN2DOE_REG(pin)						\
35394de0730Smatt 	((pin / 32) * DOE_REG_SIZE + HW_PINCTRL_DOE0)
35494de0730Smatt #define PIN2DOE_SET_REG(pin)						\
35594de0730Smatt 	((pin / 32) * DOE_REG_SIZE + HW_PINCTRL_DOE0_SET)
35694de0730Smatt #define PIN2DOE_CLR_REG(pin)						\
35794de0730Smatt 	((pin / 32) * DOE_REG_SIZE + HW_PINCTRL_DOE0_CLR)
35894de0730Smatt #define PIN2DOE_MASK(pin)	(1<<(pin % 32))
35994de0730Smatt 
36094de0730Smatt #define DRIVE_STRENGTH_4MA	0
36194de0730Smatt #define DRIVE_STRENGTH_8MA	1
36294de0730Smatt #define DRIVE_STRENGTH_12MA	2
36394de0730Smatt 
36494de0730Smatt #define MUXEL_GPIO_MODE	3
36594de0730Smatt 
36694de0730Smatt #define PINCTRL_SOFT_RST_LOOP 455 /* At least 1 us ... */
36794de0730Smatt 
36894de0730Smatt static int
imx23_pinctrl_match(device_t parent,cfdata_t match,void * aux)36968bc6eb1Sskrll imx23_pinctrl_match(device_t parent, cfdata_t match, void *aux)
37094de0730Smatt {
37194de0730Smatt 	struct apb_attach_args *aa = aux;
37294de0730Smatt 
37394de0730Smatt 	if ((aa->aa_addr == HW_PINCTRL_BASE) &&
37494de0730Smatt 	    (aa->aa_size == HW_PINCTRL_SIZE))
37594de0730Smatt 		return 1;
37694de0730Smatt 
37794de0730Smatt 	return 0;
37894de0730Smatt }
37994de0730Smatt 
38094de0730Smatt static void
imx23_pinctrl_attach(device_t parent,device_t self,void * aux)38168bc6eb1Sskrll imx23_pinctrl_attach(device_t parent, device_t self, void *aux)
38294de0730Smatt {
38368bc6eb1Sskrll 	struct imx23_pinctrl_softc *sc = device_private(self);
38494de0730Smatt 	struct apb_attach_args *aa = aux;
38568bc6eb1Sskrll 	static int imx23_pinctrl_attached = 0;
38694de0730Smatt 
38794de0730Smatt 	sc->sc_dev = self;
38894de0730Smatt 	sc->sc_iot = aa->aa_iot;
38994de0730Smatt 
39068bc6eb1Sskrll 	if (imx23_pinctrl_attached) {
39194de0730Smatt 		aprint_error_dev(sc->sc_dev, "already attached\n");
39294de0730Smatt 		return;
39394de0730Smatt 	}
39494de0730Smatt 
39594de0730Smatt 	if (bus_space_map(sc->sc_iot, aa->aa_addr, aa->aa_size, 0,
39668bc6eb1Sskrll 	    &sc->sc_hdl)) {
39794de0730Smatt 		aprint_error_dev(sc->sc_dev, "Unable to map bus space\n");
39894de0730Smatt 		return;
39994de0730Smatt 	}
40094de0730Smatt 
40194de0730Smatt #if notyet
40268bc6eb1Sskrll 	imx23_pinctrl_reset(sc);
40394de0730Smatt #endif
40494de0730Smatt 
40568bc6eb1Sskrll 	imx23_pinctrl_init(sc);
40694de0730Smatt 
40794de0730Smatt 	aprint_normal(": PIN MUX & GPIO\n");
40894de0730Smatt 
40994de0730Smatt 	/* Set pin capabilities. */
41094de0730Smatt 	int i;
41194de0730Smatt 	for(i = 0; i < GPIO_PINS; i++) {
41294de0730Smatt 		sc->pins[i].pin_caps = pin_caps[i];
41394de0730Smatt 	}
41494de0730Smatt 
41568bc6eb1Sskrll 	imx23_pinctrl_attached = 1;
41694de0730Smatt 
41794de0730Smatt 	sc->gc.gp_cookie = sc;
41868bc6eb1Sskrll 	sc->gc.gp_gc_open = imx23_pinctrl_gp_gc_open;
41968bc6eb1Sskrll 	sc->gc.gp_gc_close = imx23_pinctrl_gp_gc_close;
42068bc6eb1Sskrll 	sc->gc.gp_pin_read = imx23_pinctrl_gp_pin_read;
42168bc6eb1Sskrll 	sc->gc.gp_pin_write = imx23_pinctrl_gp_pin_write;
42268bc6eb1Sskrll 	sc->gc.gp_pin_ctl = imx23_pinctrl_gp_pin_ctl;
42394de0730Smatt 
42494de0730Smatt 	struct gpiobus_attach_args gpiobus_aa;
42594de0730Smatt 	gpiobus_aa.gba_gc = &sc->gc;
42694de0730Smatt 	gpiobus_aa.gba_npins = GPIO_PINS;
42794de0730Smatt 	gpiobus_aa.gba_pins = sc->pins;
42894de0730Smatt 
429*c7fb772bSthorpej 	config_found(self, &gpiobus_aa, gpiobus_print, CFARGS_NONE);
43094de0730Smatt 
43194de0730Smatt 	return;
43294de0730Smatt }
43394de0730Smatt 
43494de0730Smatt static int
imx23_pinctrl_activate(device_t self,enum devact act)43568bc6eb1Sskrll imx23_pinctrl_activate(device_t self, enum devact act)
43694de0730Smatt {
43794de0730Smatt 
43894de0730Smatt 	return EOPNOTSUPP;
43994de0730Smatt }
44094de0730Smatt 
44194de0730Smatt static void
imx23_pinctrl_init(struct imx23_pinctrl_softc * sc)44268bc6eb1Sskrll imx23_pinctrl_init(struct imx23_pinctrl_softc *sc)
44394de0730Smatt {
44494de0730Smatt 	_sc = sc;
44594de0730Smatt 	return;
44694de0730Smatt }
44794de0730Smatt 
44894de0730Smatt #if notyet
44994de0730Smatt /*
45094de0730Smatt  * Inspired by i.MX23 RM "39.3.10 Correct Way to Soft Reset a Block"
45194de0730Smatt  */
45294de0730Smatt static void
imx23_pinctrl_reset(struct imx23_pinctrl_softc * sc)45368bc6eb1Sskrll imx23_pinctrl_reset(struct imx23_pinctrl_softc *sc)
45494de0730Smatt {
45594de0730Smatt         unsigned int loop;
45694de0730Smatt 
45794de0730Smatt         /* Prepare for soft-reset by making sure that SFTRST is not currently
45894de0730Smatt          * asserted. Also clear CLKGATE so we can wait for its assertion below.
45994de0730Smatt          */
46094de0730Smatt         PINCTRL_WR(sc, HW_PINCTRL_CTRL_CLR, HW_PINCTRL_CTRL_SFTRST);
46194de0730Smatt 
46294de0730Smatt         /* Wait at least a microsecond for SFTRST to deassert. */
46394de0730Smatt         loop = 0;
46494de0730Smatt         while ((PINCTRL_RD(sc, HW_PINCTRL_CTRL) & HW_PINCTRL_CTRL_SFTRST) ||
46594de0730Smatt             (loop < PINCTRL_SOFT_RST_LOOP))
46694de0730Smatt                 loop++;
46794de0730Smatt 
46894de0730Smatt         /* Clear CLKGATE so we can wait for its assertion below. */
46994de0730Smatt         PINCTRL_WR(sc, HW_PINCTRL_CTRL_CLR, HW_PINCTRL_CTRL_CLKGATE);
47094de0730Smatt 
47194de0730Smatt         /* Soft-reset the block. */
47294de0730Smatt         PINCTRL_WR(sc, HW_PINCTRL_CTRL_SET, HW_PINCTRL_CTRL_SFTRST);
47394de0730Smatt 
47494de0730Smatt         /* Wait until clock is in the gated state. */
47594de0730Smatt         while (!(PINCTRL_RD(sc, HW_PINCTRL_CTRL) & HW_PINCTRL_CTRL_CLKGATE));
47694de0730Smatt 
47794de0730Smatt         /* Bring block out of reset. */
47894de0730Smatt         PINCTRL_WR(sc, HW_PINCTRL_CTRL_CLR, HW_PINCTRL_CTRL_SFTRST);
47994de0730Smatt 
48094de0730Smatt         loop = 0;
48194de0730Smatt         while ((PINCTRL_RD(sc, HW_PINCTRL_CTRL) & HW_PINCTRL_CTRL_SFTRST) ||
48294de0730Smatt             (loop < PINCTRL_SOFT_RST_LOOP))
48394de0730Smatt                 loop++;
48494de0730Smatt 
48594de0730Smatt         PINCTRL_WR(sc, HW_PINCTRL_CTRL_CLR, HW_PINCTRL_CTRL_CLKGATE);
48694de0730Smatt 
48794de0730Smatt         /* Wait until clock is in the NON-gated state. */
48894de0730Smatt         while (PINCTRL_RD(sc, HW_PINCTRL_CTRL) & HW_PINCTRL_CTRL_CLKGATE);
48994de0730Smatt 
49094de0730Smatt         return;
49194de0730Smatt }
49294de0730Smatt #endif
49394de0730Smatt 
49494de0730Smatt /*
49594de0730Smatt  * Enable external USB transceiver/HUB.
49694de0730Smatt  *
49794de0730Smatt  * PIN18/LCD_D17/USB_EN controls reset line of external USB chip on MINI and
49894de0730Smatt  * MAXI boards. We configure this pin to logic 1.
49994de0730Smatt  */
50094de0730Smatt void
imx23_pinctrl_en_usb(void)50168bc6eb1Sskrll imx23_pinctrl_en_usb(void)
50294de0730Smatt {
50368bc6eb1Sskrll 	struct imx23_pinctrl_softc *sc = _sc;
50494de0730Smatt 
50594de0730Smatt         if (sc == NULL) {
50668bc6eb1Sskrll                 aprint_error("imx23_pinctrl is not initialized");
50794de0730Smatt                 return;
50894de0730Smatt         }
50994de0730Smatt 
51068bc6eb1Sskrll 	imx23_pinctrl_gp_pin_ctl(sc, 17, GPIO_PIN_OUTPUT);
51194de0730Smatt 	delay(1000);
51268bc6eb1Sskrll 	imx23_pinctrl_gp_pin_write(sc, 17, 1);
51394de0730Smatt 
51494de0730Smatt 	return;
51594de0730Smatt }
51694de0730Smatt 
51794de0730Smatt static	int
imx23_pinctrl_gp_gc_open(void * cookie,device_t dev)51868bc6eb1Sskrll imx23_pinctrl_gp_gc_open(void *cookie, device_t dev)
51994de0730Smatt {
52094de0730Smatt 	return 0;
52194de0730Smatt }
52294de0730Smatt 
52394de0730Smatt static	void
imx23_pinctrl_gp_gc_close(void * cookie,device_t dev)52468bc6eb1Sskrll imx23_pinctrl_gp_gc_close(void *cookie, device_t dev)
52594de0730Smatt {
52694de0730Smatt 	return;
52794de0730Smatt }
52894de0730Smatt 
52994de0730Smatt static	int
imx23_pinctrl_gp_pin_read(void * cookie,int pin)53068bc6eb1Sskrll imx23_pinctrl_gp_pin_read(void *cookie, int pin)
53194de0730Smatt {
53294de0730Smatt 	int value;
53368bc6eb1Sskrll 	imx23_pinctrl_softc_t sc = (imx23_pinctrl_softc_t) cookie;
53494de0730Smatt 
53594de0730Smatt 	if (PINCTRL_RD(sc, PIN2DIN_REG(pin)) & PIN2DIN_MASK(pin))
53694de0730Smatt 		value = 1;
53794de0730Smatt 	else
53894de0730Smatt 		value = 0;
53994de0730Smatt 
54094de0730Smatt 	return value;
54194de0730Smatt }
54294de0730Smatt 
54394de0730Smatt static	void
imx23_pinctrl_gp_pin_write(void * cookie,int pin,int value)54468bc6eb1Sskrll imx23_pinctrl_gp_pin_write(void *cookie, int pin, int value)
54594de0730Smatt {
54668bc6eb1Sskrll 	imx23_pinctrl_softc_t sc = (imx23_pinctrl_softc_t) cookie;
54794de0730Smatt 
54894de0730Smatt 	if (value)
54994de0730Smatt 		PINCTRL_WR(sc, PIN2DOUT_SET_REG(pin), PIN2DOUT_MASK(pin));
55094de0730Smatt 	else
55194de0730Smatt 		PINCTRL_WR(sc, PIN2DOUT_CLR_REG(pin), PIN2DOUT_MASK(pin));
55294de0730Smatt 
55394de0730Smatt 	return;
55494de0730Smatt }
55594de0730Smatt 
55694de0730Smatt /*
55794de0730Smatt  * Configure pin as requested in flags.
55894de0730Smatt  */
55994de0730Smatt static	void
imx23_pinctrl_gp_pin_ctl(void * cookie,int pin,int flags)56068bc6eb1Sskrll imx23_pinctrl_gp_pin_ctl(void *cookie, int pin, int flags)
56194de0730Smatt {
56268bc6eb1Sskrll 	imx23_pinctrl_softc_t sc = (imx23_pinctrl_softc_t) cookie;
56394de0730Smatt 	uint32_t tmpr;
56494de0730Smatt 
56594de0730Smatt 	/* Enable GPIO pin. */
56694de0730Smatt 	tmpr = PINCTRL_RD(sc, PIN2MUXSEL_REG(pin));
56794de0730Smatt 	tmpr &= ~PIN2MUXSEL_MASK(pin);
56894de0730Smatt 	tmpr |= __SHIFTIN(MUXEL_GPIO_MODE, PIN2MUXSEL_MASK(pin));
56994de0730Smatt 	PINCTRL_WR(sc, PIN2MUXSEL_REG(pin), tmpr);
57094de0730Smatt 
57194de0730Smatt 	/* Configure pin drive strength. */
57294de0730Smatt 	tmpr = PINCTRL_RD(sc, PIN2DRIVE_REG(pin));
57394de0730Smatt 	tmpr &= ~PIN2DRIVE_MASK(pin);
57494de0730Smatt 	tmpr |= __SHIFTIN(DRIVE_STRENGTH_4MA, PIN2DRIVE_MASK(pin));
57594de0730Smatt 	PINCTRL_WR(sc, PIN2DRIVE_REG(pin), tmpr);
57694de0730Smatt 
57794de0730Smatt 	if ((flags & (GPIO_PIN_OUTPUT | GPIO_PIN_INOUT))) {
57894de0730Smatt 		/* Configure pullup resistor or gate keeper. */
57994de0730Smatt 		if (flags & GPIO_PIN_PULLUP)
58094de0730Smatt 			PINCTRL_WR(sc, PIN2PULL_SET_REG(pin),
58194de0730Smatt 				PIN2PULL_MASK(pin));
58294de0730Smatt 		else
58394de0730Smatt 			PINCTRL_WR(sc, PIN2PULL_CLR_REG(pin),
58494de0730Smatt 				PIN2PULL_MASK(pin));
58594de0730Smatt 
58694de0730Smatt 		/* Set initial pin value to logic zero. */
58794de0730Smatt 		PINCTRL_WR(sc, PIN2DOUT_CLR_REG(pin), PIN2DOUT_MASK(pin));
58894de0730Smatt 
58994de0730Smatt 		/* Enable pin output. */
59094de0730Smatt 		PINCTRL_WR(sc, PIN2DOE_SET_REG(pin), PIN2DOE_MASK(pin));
59194de0730Smatt 	}
59294de0730Smatt 
59394de0730Smatt 	if (flags & GPIO_PIN_INPUT) {
59494de0730Smatt 		/* Disable pin output. */
59594de0730Smatt 		PINCTRL_WR(sc, PIN2DOE_CLR_REG(pin), PIN2DOE_MASK(pin));
59694de0730Smatt 
59794de0730Smatt 		/* Configure pullup resistor or gate keeper. */
59894de0730Smatt 		if (flags & GPIO_PIN_PULLUP)
59994de0730Smatt 			PINCTRL_WR(sc, PIN2PULL_SET_REG(pin),
60094de0730Smatt 				PIN2PULL_MASK(pin));
60194de0730Smatt 		else
60294de0730Smatt 			PINCTRL_WR(sc, PIN2PULL_CLR_REG(pin),
60394de0730Smatt 				PIN2PULL_MASK(pin));
60494de0730Smatt 	}
60594de0730Smatt 
60694de0730Smatt 	return;
60794de0730Smatt }
608