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