Lines Matching +full:pin +full:- +full:mux
1 // SPDX-License-Identifier: GPL-2.0+
13 #include "pinctrl-rockchip.h"
19 static int rockchip_verify_config(struct udevice *dev, u32 bank, u32 pin) in rockchip_verify_config() argument
22 struct rockchip_pin_ctrl *ctrl = priv->ctrl; in rockchip_verify_config()
24 if (bank >= ctrl->nr_banks) { in rockchip_verify_config()
25 debug("pin conf bank %d >= nbanks %d\n", bank, ctrl->nr_banks); in rockchip_verify_config()
26 return -EINVAL; in rockchip_verify_config()
29 if (pin >= MAX_ROCKCHIP_GPIO_PER_BANK) { in rockchip_verify_config()
30 debug("pin conf pin %d >= %d\n", pin, in rockchip_verify_config()
32 return -EINVAL; in rockchip_verify_config()
38 static void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin, in rockchip_get_recalced_mux() argument
41 struct rockchip_pinctrl_priv *priv = bank->priv; in rockchip_get_recalced_mux()
42 struct rockchip_pin_ctrl *ctrl = priv->ctrl; in rockchip_get_recalced_mux()
46 for (i = 0; i < ctrl->niomux_recalced; i++) { in rockchip_get_recalced_mux()
47 data = &ctrl->iomux_recalced[i]; in rockchip_get_recalced_mux()
48 if (data->num == bank->bank_num && in rockchip_get_recalced_mux()
49 data->pin == pin) in rockchip_get_recalced_mux()
53 if (i >= ctrl->niomux_recalced) in rockchip_get_recalced_mux()
56 *reg = data->reg; in rockchip_get_recalced_mux()
57 *mask = data->mask; in rockchip_get_recalced_mux()
58 *bit = data->bit; in rockchip_get_recalced_mux()
61 static bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin, in rockchip_get_mux_route() argument
62 int mux, u32 *reg, u32 *value) in rockchip_get_mux_route() argument
64 struct rockchip_pinctrl_priv *priv = bank->priv; in rockchip_get_mux_route()
65 struct rockchip_pin_ctrl *ctrl = priv->ctrl; in rockchip_get_mux_route()
69 for (i = 0; i < ctrl->niomux_routes; i++) { in rockchip_get_mux_route()
70 data = &ctrl->iomux_routes[i]; in rockchip_get_mux_route()
71 if (data->bank_num == bank->bank_num && in rockchip_get_mux_route()
72 data->pin == pin && data->func == mux) in rockchip_get_mux_route()
76 if (i >= ctrl->niomux_routes) in rockchip_get_mux_route()
79 *reg = data->route_offset; in rockchip_get_mux_route()
80 *value = data->route_val; in rockchip_get_mux_route()
85 static int rockchip_get_mux_data(int mux_type, int pin, u8 *bit, int *mask) in rockchip_get_mux_data() argument
90 if ((pin % 8) >= 4) in rockchip_get_mux_data()
92 *bit = (pin % 4) * 4; in rockchip_get_mux_data()
99 if ((pin % 8) >= 5) in rockchip_get_mux_data()
101 *bit = (pin % 8 % 5) * 3; in rockchip_get_mux_data()
104 *bit = (pin % 8) * 2; in rockchip_get_mux_data()
111 static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) in rockchip_get_mux() argument
113 struct rockchip_pinctrl_priv *priv = bank->priv; in rockchip_get_mux()
114 int iomux_num = (pin / 8); in rockchip_get_mux()
121 return -EINVAL; in rockchip_get_mux()
123 if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) { in rockchip_get_mux()
124 debug("pin %d is unrouted\n", pin); in rockchip_get_mux()
125 return -EINVAL; in rockchip_get_mux()
128 if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) in rockchip_get_mux()
131 regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) in rockchip_get_mux()
132 ? priv->regmap_pmu : priv->regmap_base; in rockchip_get_mux()
134 /* get basic quadrupel of mux registers and the correct reg inside */ in rockchip_get_mux()
135 mux_type = bank->iomux[iomux_num].type; in rockchip_get_mux()
136 reg = bank->iomux[iomux_num].offset; in rockchip_get_mux()
137 reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask); in rockchip_get_mux()
139 if (bank->recalced_mask & BIT(pin)) in rockchip_get_mux()
140 rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); in rockchip_get_mux()
152 struct rockchip_pin_ctrl *ctrl = priv->ctrl; in rockchip_pinctrl_get_gpio_mux()
154 return rockchip_get_mux(&ctrl->pin_banks[banknum], index); in rockchip_pinctrl_get_gpio_mux()
158 int pin, int mux) in rockchip_verify_mux() argument
160 int iomux_num = (pin / 8); in rockchip_verify_mux()
163 return -EINVAL; in rockchip_verify_mux()
165 if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) { in rockchip_verify_mux()
166 debug("pin %d is unrouted\n", pin); in rockchip_verify_mux()
167 return -EINVAL; in rockchip_verify_mux()
170 if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) { in rockchip_verify_mux()
171 if (mux != IOMUX_GPIO_ONLY) { in rockchip_verify_mux()
172 debug("pin %d only supports a gpio mux\n", pin); in rockchip_verify_mux()
173 return -ENOTSUPP; in rockchip_verify_mux()
181 * Set a new mux function for a pin.
187 * All pin settings seem to be 2 bit wide in both the upper and lower
189 * @bank: pin bank to change
190 * @pin: pin to change
191 * @mux: new mux function to set
193 static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) in rockchip_set_mux() argument
195 struct rockchip_pinctrl_priv *priv = bank->priv; in rockchip_set_mux()
196 int iomux_num = (pin / 8); in rockchip_set_mux()
202 ret = rockchip_verify_mux(bank, pin, mux); in rockchip_set_mux()
206 if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) in rockchip_set_mux()
209 debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux); in rockchip_set_mux()
211 regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) in rockchip_set_mux()
212 ? priv->regmap_pmu : priv->regmap_base; in rockchip_set_mux()
214 /* get basic quadrupel of mux registers and the correct reg inside */ in rockchip_set_mux()
215 mux_type = bank->iomux[iomux_num].type; in rockchip_set_mux()
216 reg = bank->iomux[iomux_num].offset; in rockchip_set_mux()
217 reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask); in rockchip_set_mux()
219 if (bank->recalced_mask & BIT(pin)) in rockchip_set_mux()
220 rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); in rockchip_set_mux()
222 if (bank->route_mask & BIT(pin)) { in rockchip_set_mux()
223 if (rockchip_get_mux_route(bank, pin, mux, &route_reg, in rockchip_set_mux()
238 data |= (mux & mask) << bit; in rockchip_set_mux()
245 { 2, 4, 8, 12, -1, -1, -1, -1 },
246 { 3, 6, 9, 12, -1, -1, -1, -1 },
247 { 5, 10, 15, 20, -1, -1, -1, -1 },
255 struct rockchip_pinctrl_priv *priv = bank->priv; in rockchip_set_drive_perpin()
256 struct rockchip_pin_ctrl *ctrl = priv->ctrl; in rockchip_set_drive_perpin()
262 int drv_type = bank->drv[pin_num / 8].drv_type & (~DRV_TYPE_IO_MASK); in rockchip_set_drive_perpin()
264 debug("setting drive of GPIO%d-%d to %d\n", bank->bank_num, in rockchip_set_drive_perpin()
267 ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit); in rockchip_set_drive_perpin()
269 ret = -EINVAL; in rockchip_set_drive_perpin()
295 * drive-strength offset is special, as it is spread in rockchip_set_drive_perpin()
315 bit -= 16; in rockchip_set_drive_perpin()
320 return -EINVAL; in rockchip_set_drive_perpin()
331 return -EINVAL; in rockchip_set_drive_perpin()
334 if (bank->drv[pin_num / 8].drv_type & DRV_TYPE_WRITABLE_32BIT) { in rockchip_set_drive_perpin()
336 data &= ~(((1 << rmask_bits) - 1) << bit); in rockchip_set_drive_perpin()
339 data = ((1 << rmask_bits) - 1) << (bit + 16); in rockchip_set_drive_perpin()
365 struct rockchip_pinctrl_priv *priv = bank->priv; in rockchip_set_pull()
366 struct rockchip_pin_ctrl *ctrl = priv->ctrl; in rockchip_set_pull()
372 debug("setting pull of GPIO%d-%d to %d\n", bank->bank_num, in rockchip_set_pull()
375 ctrl->pull_calc_reg(bank, pin_num, ®map, ®, &bit); in rockchip_set_pull()
377 switch (ctrl->type) { in rockchip_set_pull()
394 pull_type = bank->pull_type[pin_num / 8] & (~PULL_TYPE_IO_MASK); in rockchip_set_pull()
395 ret = -EINVAL; in rockchip_set_pull()
409 if (bank->pull_type[pin_num / 8] & PULL_TYPE_WRITABLE_32BIT) { in rockchip_set_pull()
411 data &= ~(((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << bit); in rockchip_set_pull()
414 data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); in rockchip_set_pull()
422 return -EINVAL; in rockchip_set_pull()
431 struct rockchip_pinctrl_priv *priv = bank->priv; in rockchip_set_schmitt()
432 struct rockchip_pin_ctrl *ctrl = priv->ctrl; in rockchip_set_schmitt()
438 debug("setting input schmitt of GPIO%d-%d to %d\n", bank->bank_num, in rockchip_set_schmitt()
441 ret = ctrl->schmitt_calc_reg(bank, pin_num, ®map, ®, &bit); in rockchip_set_schmitt()
457 switch (ctrl->type) { in rockchip_pinconf_pull_valid()
473 /* set the pin config settings for a specified pin */
475 u32 pin, u32 param, u32 arg) in rockchip_pinconf_set() argument
477 struct rockchip_pinctrl_priv *priv = bank->priv; in rockchip_pinconf_set()
478 struct rockchip_pin_ctrl *ctrl = priv->ctrl; in rockchip_pinconf_set()
483 rc = rockchip_set_pull(bank, pin, param); in rockchip_pinconf_set()
493 return -ENOTSUPP; in rockchip_pinconf_set()
496 return -EINVAL; in rockchip_pinconf_set()
498 rc = rockchip_set_pull(bank, pin, param); in rockchip_pinconf_set()
504 if (!ctrl->drv_calc_reg) in rockchip_pinconf_set()
505 return -ENOTSUPP; in rockchip_pinconf_set()
507 rc = rockchip_set_drive_perpin(bank, pin, arg); in rockchip_pinconf_set()
513 if (!ctrl->schmitt_calc_reg) in rockchip_pinconf_set()
514 return -ENOTSUPP; in rockchip_pinconf_set()
516 rc = rockchip_set_schmitt(bank, pin, arg); in rockchip_pinconf_set()
529 { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
530 { "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 },
531 { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
532 { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
533 { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
534 { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
535 { "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
536 { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
537 { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
550 if (!strcmp(property, p->property)) { in rockchip_pinconf_prop_name_to_param()
551 *default_value = p->default_value; in rockchip_pinconf_prop_name_to_param()
552 return p->param; in rockchip_pinconf_prop_name_to_param()
557 return -EPERM; in rockchip_pinconf_prop_name_to_param()
564 struct rockchip_pin_ctrl *ctrl = priv->ctrl;
566 u32 bank, pin, mux, conf, arg, default_val; local
578 const void *blob = gd->fdt_blob;
583 return -EINVAL;
590 return -EINVAL;
598 pin = cells[4 * i + 1];
599 mux = cells[4 * i + 2];
602 ret = rockchip_verify_config(dev, bank, pin);
606 ret = rockchip_set_mux(&ctrl->pin_banks[bank], pin, mux);
612 return -ENODEV;
615 for (pp = np->properties; pp; pp = pp->next) {
616 prop_name = pp->name;
617 prop_len = pp->length;
618 value = pp->value;
625 return -ENOENT;
637 ret = rockchip_pinconf_set(&ctrl->pin_banks[bank], pin,
664 grf_offs = ctrl->grf_mux_offset;
665 pmu_offs = ctrl->pmu_mux_offset;
666 drv_pmu_offs = ctrl->pmu_drv_offset;
667 drv_grf_offs = ctrl->grf_drv_offset;
668 bank = ctrl->pin_banks;
670 for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
673 bank->priv = priv;
674 bank->pin_base = ctrl->nr_pins;
675 ctrl->nr_pins += bank->nr_pins;
679 struct rockchip_iomux *iom = &bank->iomux[j];
680 struct rockchip_drv *drv = &bank->drv[j];
683 if (bank_pins >= bank->nr_pins)
687 if (iom->offset >= 0) {
688 if (iom->type & IOMUX_SOURCE_PMU)
689 pmu_offs = iom->offset;
691 grf_offs = iom->offset;
693 iom->offset = (iom->type & IOMUX_SOURCE_PMU) ?
698 if (drv->offset >= 0) {
699 if (iom->type & IOMUX_SOURCE_PMU)
700 drv_pmu_offs = drv->offset;
702 drv_grf_offs = drv->offset;
704 drv->offset = (iom->type & IOMUX_SOURCE_PMU) ?
709 i, j, iom->offset, drv->offset);
715 inc = (iom->type & (IOMUX_WIDTH_4BIT |
717 if (iom->type & IOMUX_SOURCE_PMU)
724 * 3bit drive-strenth'es are spread over two registers.
726 if ((drv->drv_type == DRV_TYPE_IO_1V8_3V0_AUTO) ||
727 (drv->drv_type == DRV_TYPE_IO_3V3_ONLY))
732 if (iom->type & IOMUX_SOURCE_PMU)
740 /* calculate the per-bank recalced_mask */
741 for (j = 0; j < ctrl->niomux_recalced; j++) {
742 int pin = 0; local
744 if (ctrl->iomux_recalced[j].num == bank->bank_num) {
745 pin = ctrl->iomux_recalced[j].pin;
746 bank->recalced_mask |= BIT(pin);
750 /* calculate the per-bank route_mask */
751 for (j = 0; j < ctrl->niomux_routes; j++) {
752 int pin = 0; local
754 if (ctrl->iomux_routes[j].bank_num == bank->bank_num) {
755 pin = ctrl->iomux_routes[j].pin;
756 bank->route_mask |= BIT(pin);
780 /* get grf-reg base address */
784 return -ENODEV;
786 priv->regmap_base = regmap;
788 /* option: get pmu-reg base address */
792 /* get pmugrf-reg base address */
796 return -ENODEV;
798 priv->regmap_pmu = regmap;
804 return -EINVAL;
807 priv->ctrl = ctrl;