protocol */ - DEVMETHOD(gpio_get_bus, qcom_tlmm_get_bus), - DEVMETHOD(gpio_pin_max, qcom_tlmm_pin_max), - DEVMETHOD(gpio_pin_getname, qcom_tlmm_pin_getname), - DEVMETHOD(gpio_pin_getflags, qcom_tlmm_pin_getflags), - DEVMETHOD(gpio_pin_getcaps, qcom_tlmm_pin_getcaps), - DEVMETHOD(gpio_pin_setflags, qcom_tlmm_pin_setflags), - DEVMETHOD(gpio_pin_get, qcom_tlmm_pin_get), - DEVMETHOD(gpio_pin_set, qcom_tlmm_pin_set), - DEVMETHOD(gpio_pin_toggle, qcom_tlmm_pin_toggle), - - /* OFW */ - DEVMETHOD(ofw_bus_get_node, qcom_tlmm_pin_get_node), - - /* fdt_pinctrl interface */ - DEVMETHOD(fdt_pinctrl_configure, qcom_tlmm_pinctrl_configure), - - {0, 0}, -}; - -static driver_t qcom_tlmm_ipq4018_driver = { - "gpio", - qcom_tlmm_ipq4018_methods, - sizeof(struct qcom_tlmm_softc), -}; - -EARLY_DRIVER_MODULE(qcom_tlmm_ipq4018, simplebus, qcom_tlmm_ipq4018_driver, - NULL, NULL, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE); -EARLY_DRIVER_MODULE(qcom_tlmm_ipq4018, ofwbus, qcom_tlmm_ipq4018_driver, - NULL, NULL, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE); -MODULE_VERSION(qcom_tlmm_ipq4018, 1); diff --git a/sys/dev/qcom_tlmm/qcom_tlmm_pin.c b/sys/dev/qcom_tlmm/qcom_tlmm_pin.c index be7b37f21156..27d6f904d664 100644 --- a/sys/dev/qcom_tlmm/qcom_tlmm_pin.c +++ b/sys/dev/qcom_tlmm/qcom_tlmm_pin.c @@ -85,11 +85,11 @@ qcom_tlmm_pin_configure(struct qcom_tlmm_softc *sc, * pin value before we flip on oe_output. */ pin->gp_flags |= GPIO_PIN_OUTPUT; - qcom_tlmm_ipq4018_hw_pin_set_oe_output(sc, + sc->sc_hw->qcom_tlmm_hw_pin_set_oe_output(sc, pin->gp_pin); } else { pin->gp_flags |= GPIO_PIN_INPUT; - qcom_tlmm_ipq4018_hw_pin_set_oe_input(sc, + sc->sc_hw->qcom_tlmm_hw_pin_set_oe_input(sc, pin->gp_pin); } } @@ -99,20 +99,20 @@ qcom_tlmm_pin_configure(struct qcom_tlmm_softc *sc, */ if (flags & GPIO_PIN_PULLUP) { pin->gp_flags |= GPIO_PIN_PULLUP; - qcom_tlmm_ipq4018_hw_pin_set_pupd_config(sc, pin->gp_pin, + sc->sc_hw->qcom_tlmm_hw_pin_set_pupd_config(sc, pin->gp_pin, QCOM_TLMM_PIN_PUPD_CONFIG_PULL_UP); } else if (flags & GPIO_PIN_PULLDOWN) { pin->gp_flags |= GPIO_PIN_PULLDOWN; - qcom_tlmm_ipq4018_hw_pin_set_pupd_config(sc, pin->gp_pin, + sc->sc_hw->qcom_tlmm_hw_pin_set_pupd_config(sc, pin->gp_pin, QCOM_TLMM_PIN_PUPD_CONFIG_PULL_DOWN); } else if ((flags & (GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN)) == (GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN)) { pin->gp_flags |= GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN; - qcom_tlmm_ipq4018_hw_pin_set_pupd_config(sc, pin->gp_pin, + sc->sc_hw->qcom_tlmm_hw_pin_set_pupd_config(sc, pin->gp_pin, QCOM_TLMM_PIN_PUPD_CONFIG_BUS_HOLD); } else { pin->gp_flags &= ~(GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN); - qcom_tlmm_ipq4018_hw_pin_set_pupd_config(sc, pin->gp_pin, + sc->sc_hw->qcom_tlmm_hw_pin_set_pupd_config(sc, pin->gp_pin, QCOM_TLMM_PIN_PUPD_CONFIG_DISABLE); } } @@ -169,12 +169,12 @@ qcom_tlmm_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) GPIO_LOCK(sc); /* Lookup function - see what it is, whether we're a GPIO line */ - ret = qcom_tlmm_ipq4018_hw_pin_get_function(sc, pin, &val); + ret = sc->sc_hw->qcom_tlmm_hw_pin_get_function(sc, pin, &val); if (ret != 0) goto done; /* Lookup input/output state */ - ret = qcom_tlmm_ipq4018_hw_pin_get_oe_state(sc, pin, &is_output); + ret = sc->sc_hw->qcom_tlmm_hw_pin_get_oe_state(sc, pin, &is_output); if (ret != 0) goto done; if (is_output) @@ -183,7 +183,7 @@ qcom_tlmm_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) *flags |= GPIO_PIN_INPUT; /* Lookup pull-up / pull-down state */ - ret = qcom_tlmm_ipq4018_hw_pin_get_pupd_config(sc, pin, + ret = sc->sc_hw->qcom_tlmm_hw_pin_get_pupd_config(sc, pin, &pupd_config); if (ret != 0) goto done; @@ -251,7 +251,7 @@ qcom_tlmm_pin_set(device_t dev, uint32_t pin, unsigned int value) return (EINVAL); GPIO_LOCK(sc); - ret = qcom_tlmm_ipq4018_hw_pin_set_output_value(sc, pin, value); + ret = sc->sc_hw->qcom_tlmm_hw_pin_set_output_value(sc, pin, value); GPIO_UNLOCK(sc); return (ret); @@ -267,7 +267,7 @@ qcom_tlmm_pin_get(device_t dev, uint32_t pin, unsigned int *val) return (EINVAL); GPIO_LOCK(sc); - ret = qcom_tlmm_ipq4018_hw_pin_get_input_value(sc, pin, val); + ret = sc->sc_hw->qcom_tlmm_hw_pin_get_input_value(sc, pin, val); GPIO_UNLOCK(sc); return (ret); @@ -283,7 +283,7 @@ qcom_tlmm_pin_toggle(device_t dev, uint32_t pin) return (EINVAL); GPIO_LOCK(sc); - ret = qcom_tlmm_ipq4018_hw_pin_toggle_output_value(sc, pin); + ret = sc->sc_hw->qcom_tlmm_hw_pin_toggle_output_value(sc, pin); GPIO_UNLOCK(sc); return (ret); diff --git a/sys/dev/qcom_tlmm/qcom_tlmm_pinmux.c b/sys/dev/qcom_tlmm/qcom_tlmm_pinmux.c index a4b4dffa3dbb..59e97dfe7602 100644 --- a/sys/dev/qcom_tlmm/qcom_tlmm_pinmux.c +++ b/sys/dev/qcom_tlmm/qcom_tlmm_pinmux.c @@ -238,7 +238,7 @@ qcom_tlmm_pinctrl_config_gmux(struct qcom_tlmm_softc *sc, char *pin_name, __func__, gmux->id, tmp); - err = qcom_tlmm_ipq4018_hw_pin_set_function(sc, gmux->id, + err = sc->sc_hw->qcom_tlmm_hw_pin_set_function(sc, gmux->id, tmp); if (err != 0) { device_printf(sc->dev, @@ -263,7 +263,7 @@ qcom_tlmm_pinctrl_config_gmux(struct qcom_tlmm_softc *sc, char *pin_name, cfg->params[i]); switch (i) { case PIN_ID_BIAS_DISABLE: - err = qcom_tlmm_ipq4018_hw_pin_set_pupd_config(sc, + err = sc->sc_hw->qcom_tlmm_hw_pin_set_pupd_config(sc, gmux->id, QCOM_TLMM_PIN_PUPD_CONFIG_DISABLE); if (err != 0) { device_printf(sc->dev, @@ -274,7 +274,7 @@ qcom_tlmm_pinctrl_config_gmux(struct qcom_tlmm_softc *sc, char *pin_name, } break; case PIN_ID_BIAS_PULL_DOWN: - err = qcom_tlmm_ipq4018_hw_pin_set_pupd_config(sc, + err = sc->sc_hw->qcom_tlmm_hw_pin_set_pupd_config(sc, gmux->id, QCOM_TLMM_PIN_PUPD_CONFIG_PULL_DOWN); if (err != 0) { device_printf(sc->dev, @@ -285,7 +285,7 @@ qcom_tlmm_pinctrl_config_gmux(struct qcom_tlmm_softc *sc, char *pin_name, } break; case PIN_ID_BIAS_BUS_HOLD: - err = qcom_tlmm_ipq4018_hw_pin_set_pupd_config(sc, + err = sc->sc_hw->qcom_tlmm_hw_pin_set_pupd_config(sc, gmux->id, QCOM_TLMM_PIN_PUPD_CONFIG_BUS_HOLD); if (err != 0) { device_printf(sc->dev, @@ -297,7 +297,7 @@ qcom_tlmm_pinctrl_config_gmux(struct qcom_tlmm_softc *sc, char *pin_name, break; case PIN_ID_BIAS_PULL_UP: - err = qcom_tlmm_ipq4018_hw_pin_set_pupd_config(sc, + err = sc->sc_hw->qcom_tlmm_hw_pin_set_pupd_config(sc, gmux->id, QCOM_TLMM_PIN_PUPD_CONFIG_PULL_UP); if (err != 0) { device_printf(sc->dev, @@ -308,7 +308,7 @@ qcom_tlmm_pinctrl_config_gmux(struct qcom_tlmm_softc *sc, char *pin_name, } break; case PIN_ID_OUTPUT_LOW: - err = qcom_tlmm_ipq4018_hw_pin_set_oe_output(sc, + err = sc->sc_hw->qcom_tlmm_hw_pin_set_oe_output(sc, gmux->id); if (err != 0) { device_printf(sc->dev, @@ -317,7 +317,7 @@ qcom_tlmm_pinctrl_config_gmux(struct qcom_tlmm_softc *sc, char *pin_name, __func__, gmux->id, err); goto done; } - err = qcom_tlmm_ipq4018_hw_pin_set_output_value( + err = sc->sc_hw->qcom_tlmm_hw_pin_set_output_value( sc, gmux->id, 0); if (err != 0) { device_printf(sc->dev, @@ -328,7 +328,7 @@ qcom_tlmm_pinctrl_config_gmux(struct qcom_tlmm_softc *sc, char *pin_name, } break; case PIN_ID_OUTPUT_HIGH: - err = qcom_tlmm_ipq4018_hw_pin_set_oe_output(sc, + err = sc->sc_hw->qcom_tlmm_hw_pin_set_oe_output(sc, gmux->id); if (err != 0) { device_printf(sc->dev, @@ -337,7 +337,7 @@ qcom_tlmm_pinctrl_config_gmux(struct qcom_tlmm_softc *sc, char *pin_name, __func__, gmux->id, err); goto done; } - err = qcom_tlmm_ipq4018_hw_pin_set_output_value( + err = sc->sc_hw->qcom_tlmm_hw_pin_set_output_value( sc, gmux->id, 1); if (err != 0) { device_printf(sc->dev, @@ -348,7 +348,7 @@ qcom_tlmm_pinctrl_config_gmux(struct qcom_tlmm_softc *sc, char *pin_name, } break; case PIN_ID_DRIVE_STRENGTH: - err = qcom_tlmm_ipq4018_hw_pin_set_drive_strength(sc, + err = sc->sc_hw->qcom_tlmm_hw_pin_set_drive_strength(sc, gmux->id, cfg->params[i]); if (err != 0) { device_printf(sc->dev, @@ -360,7 +360,7 @@ qcom_tlmm_pinctrl_config_gmux(struct qcom_tlmm_softc *sc, char *pin_name, } break; case PIN_ID_VM_ENABLE: - err = qcom_tlmm_ipq4018_hw_pin_set_vm(sc, + err = sc->sc_hw->qcom_tlmm_hw_pin_set_vm(sc, gmux->id, true); if (err != 0) { device_printf(sc->dev, @@ -371,7 +371,7 @@ qcom_tlmm_pinctrl_config_gmux(struct qcom_tlmm_softc *sc, char *pin_name, } break; case PIN_ID_VM_DISABLE: - err = qcom_tlmm_ipq4018_hw_pin_set_vm(sc, + err = sc->sc_hw->qcom_tlmm_hw_pin_set_vm(sc, gmux->id, false); if (err != 0) { device_printf(sc->dev, @@ -382,7 +382,7 @@ qcom_tlmm_pinctrl_config_gmux(struct qcom_tlmm_softc *sc, char *pin_name, } break; case PIN_ID_DRIVE_OPEN_DRAIN: - err = qcom_tlmm_ipq4018_hw_pin_set_open_drain(sc, + err = sc->sc_hw->qcom_tlmm_hw_pin_set_open_drain(sc, gmux->id, true); if (err != 0) { device_printf(sc->dev, @@ -394,7 +394,7 @@ qcom_tlmm_pinctrl_config_gmux(struct qcom_tlmm_softc *sc, char *pin_name, break; case PIN_ID_INPUT_ENABLE: /* Configure pin as an input */ - err = qcom_tlmm_ipq4018_hw_pin_set_oe_input(sc, + err = sc->sc_hw->qcom_tlmm_hw_pin_set_oe_input(sc, gmux->id); if (err != 0) { device_printf(sc->dev, diff --git a/sys/dev/qcom_tlmm/qcom_tlmm_var.h b/sys/dev/qcom_tlmm/qcom_tlmm_var.h index 1fea18275397..4fd37f83192e 100644 --- a/sys/dev/qcom_tlmm/qcom_tlmm_var.h +++ b/sys/dev/qcom_tlmm/qcom_tlmm_var.h @@ -49,6 +49,10 @@ #define GPIO_CLEAR_BITS(sc, reg, bits) \ GPIO_WRITE(sc, reg, GPIO_READ(sc, (reg)) & ~(bits)) +typedef enum { + QCOM_TLMM_CHIPSET_NONE = 0, + QCOM_TLMM_CHIPSET_IPQ4018 = 1, +} qcom_tlmm_chipset_t; enum prop_id { PIN_ID_BIAS_DISABLE = 0, @@ -141,6 +145,45 @@ struct qcom_tlmm_spec_pin { uint32_t hdrv_shift; }; +struct qcom_tlmm_softc; + +struct qcom_tlmm_hw_callbacks { + int (*qcom_tlmm_hw_pin_set_function)(struct qcom_tlmm_softc *, + int, int); + int (*qcom_tlmm_hw_pin_get_function)(struct qcom_tlmm_softc *, + int, int *); + int (*qcom_tlmm_hw_pin_set_oe_output)(struct qcom_tlmm_softc *, + int); + int (*qcom_tlmm_hw_pin_set_oe_input)(struct qcom_tlmm_softc *, + int); + int (*qcom_tlmm_hw_pin_get_oe_state)(struct qcom_tlmm_softc *, + int, bool *); + int (*qcom_tlmm_hw_pin_set_output_value)(struct qcom_tlmm_softc *, + uint32_t, unsigned int); + int (*qcom_tlmm_hw_pin_get_output_value)(struct qcom_tlmm_softc *, + uint32_t, unsigned int *); + int (*qcom_tlmm_hw_pin_get_input_value)(struct qcom_tlmm_softc *, + uint32_t, unsigned int *); + int (*qcom_tlmm_hw_pin_toggle_output_value)(struct qcom_tlmm_softc *, + uint32_t); + int (*qcom_tlmm_hw_pin_set_pupd_config)(struct qcom_tlmm_softc *, + uint32_t, qcom_tlmm_pin_pupd_config_t); + int (*qcom_tlmm_hw_pin_get_pupd_config)(struct qcom_tlmm_softc *, + uint32_t, qcom_tlmm_pin_pupd_config_t *); + int (*qcom_tlmm_hw_pin_set_drive_strength)(struct qcom_tlmm_softc *, + uint32_t, uint8_t); + int (*qcom_tlmm_hw_pin_get_drive_strength)(struct qcom_tlmm_softc *, + uint32_t, uint8_t *); + int (*qcom_tlmm_hw_pin_set_vm)(struct qcom_tlmm_softc *, + uint32_t, bool); + int (*qcom_tlmm_hw_pin_get_vm)(struct qcom_tlmm_softc *, + uint32_t, bool *); + int (*qcom_tlmm_hw_pin_set_open_drain)(struct qcom_tlmm_softc *, + uint32_t, bool); + int (*qcom_tlmm_hw_pin_get_open_drain)(struct qcom_tlmm_softc *, + uint32_t, bool *); +}; + struct qcom_tlmm_softc { device_t dev; device_t busdev; @@ -153,6 +196,10 @@ struct qcom_tlmm_softc { int gpio_npins; struct gpio_pin *gpio_pins; uint32_t sc_debug; + qcom_tlmm_chipset_t sc_chipset; + void (*sc_attach_func)(struct qcom_tlmm_softc *); + + struct qcom_tlmm_hw_callbacks *sc_hw; const struct qcom_tlmm_gpio_mux *gpio_muxes; const struct qcom_tlmm_spec_pin *spec_pins;