diff options
Diffstat (limited to 'drivers/pinctrl')
20 files changed, 1479 insertions, 148 deletions
diff --git a/drivers/pinctrl/intel/pinctrl-cannonlake.c b/drivers/pinctrl/intel/pinctrl-cannonlake.c index e130599be571..6243e7d95e7e 100644 --- a/drivers/pinctrl/intel/pinctrl-cannonlake.c +++ b/drivers/pinctrl/intel/pinctrl-cannonlake.c @@ -23,13 +23,16 @@ #define CNL_HOSTSW_OWN 0x0b0 #define CNL_GPI_IE 0x120 -#define CNL_GPP(r, s, e) \ +#define CNL_GPP(r, s, e, g) \ { \ .reg_num = (r), \ .base = (s), \ .size = ((e) - (s) + 1), \ + .gpio_base = (g), \ } +#define CNL_NO_GPIO -1 + #define CNL_COMMUNITY(b, s, e, g) \ { \ .barno = (b), \ @@ -363,32 +366,32 @@ static const struct pinctrl_pin_desc cnlh_pins[] = { }; static const struct intel_padgroup cnlh_community0_gpps[] = { - CNL_GPP(0, 0, 24), /* GPP_A */ - CNL_GPP(1, 25, 50), /* GPP_B */ + CNL_GPP(0, 0, 24, 0), /* GPP_A */ + CNL_GPP(1, 25, 50, 32), /* GPP_B */ }; static const struct intel_padgroup cnlh_community1_gpps[] = { - CNL_GPP(0, 51, 74), /* GPP_C */ - CNL_GPP(1, 75, 98), /* GPP_D */ - CNL_GPP(2, 99, 106), /* GPP_G */ - CNL_GPP(3, 107, 114), /* AZA */ - CNL_GPP(4, 115, 146), /* vGPIO_0 */ - CNL_GPP(5, 147, 154), /* vGPIO_1 */ + CNL_GPP(0, 51, 74, 64), /* GPP_C */ + CNL_GPP(1, 75, 98, 96), /* GPP_D */ + CNL_GPP(2, 99, 106, 128), /* GPP_G */ + CNL_GPP(3, 107, 114, CNL_NO_GPIO), /* AZA */ + CNL_GPP(4, 115, 146, 160), /* vGPIO_0 */ + CNL_GPP(5, 147, 154, CNL_NO_GPIO), /* vGPIO_1 */ }; static const struct intel_padgroup cnlh_community3_gpps[] = { - CNL_GPP(0, 155, 178), /* GPP_K */ - CNL_GPP(1, 179, 202), /* GPP_H */ - CNL_GPP(2, 203, 215), /* GPP_E */ - CNL_GPP(3, 216, 239), /* GPP_F */ - CNL_GPP(4, 240, 248), /* SPI */ + CNL_GPP(0, 155, 178, 192), /* GPP_K */ + CNL_GPP(1, 179, 202, 224), /* GPP_H */ + CNL_GPP(2, 203, 215, 258), /* GPP_E */ + CNL_GPP(3, 216, 239, 288), /* GPP_F */ + CNL_GPP(4, 240, 248, CNL_NO_GPIO), /* SPI */ }; static const struct intel_padgroup cnlh_community4_gpps[] = { - CNL_GPP(0, 249, 259), /* CPU */ - CNL_GPP(1, 260, 268), /* JTAG */ - CNL_GPP(2, 269, 286), /* GPP_I */ - CNL_GPP(3, 287, 298), /* GPP_J */ + CNL_GPP(0, 249, 259, CNL_NO_GPIO), /* CPU */ + CNL_GPP(1, 260, 268, CNL_NO_GPIO), /* JTAG */ + CNL_GPP(2, 269, 286, 320), /* GPP_I */ + CNL_GPP(3, 287, 298, 352), /* GPP_J */ }; static const unsigned int cnlh_spi0_pins[] = { 40, 41, 42, 43 }; @@ -785,25 +788,25 @@ static const struct intel_function cnllp_functions[] = { }; static const struct intel_padgroup cnllp_community0_gpps[] = { - CNL_GPP(0, 0, 24), /* GPP_A */ - CNL_GPP(1, 25, 50), /* GPP_B */ - CNL_GPP(2, 51, 58), /* GPP_G */ - CNL_GPP(3, 59, 67), /* SPI */ + CNL_GPP(0, 0, 24, 0), /* GPP_A */ + CNL_GPP(1, 25, 50, 32), /* GPP_B */ + CNL_GPP(2, 51, 58, 64), /* GPP_G */ + CNL_GPP(3, 59, 67, CNL_NO_GPIO), /* SPI */ }; static const struct intel_padgroup cnllp_community1_gpps[] = { - CNL_GPP(0, 68, 92), /* GPP_D */ - CNL_GPP(1, 93, 116), /* GPP_F */ - CNL_GPP(2, 117, 140), /* GPP_H */ - CNL_GPP(3, 141, 172), /* vGPIO */ - CNL_GPP(4, 173, 180), /* vGPIO */ + CNL_GPP(0, 68, 92, 96), /* GPP_D */ + CNL_GPP(1, 93, 116, 128), /* GPP_F */ + CNL_GPP(2, 117, 140, 160), /* GPP_H */ + CNL_GPP(3, 141, 172, 192), /* vGPIO */ + CNL_GPP(4, 173, 180, 224), /* vGPIO */ }; static const struct intel_padgroup cnllp_community4_gpps[] = { - CNL_GPP(0, 181, 204), /* GPP_C */ - CNL_GPP(1, 205, 228), /* GPP_E */ - CNL_GPP(2, 229, 237), /* JTAG */ - CNL_GPP(3, 238, 243), /* HVCMOS */ + CNL_GPP(0, 181, 204, 256), /* GPP_C */ + CNL_GPP(1, 205, 228, 288), /* GPP_E */ + CNL_GPP(2, 229, 237, CNL_NO_GPIO), /* JTAG */ + CNL_GPP(3, 238, 243, CNL_NO_GPIO), /* HVCMOS */ }; static const struct intel_community cnllp_communities[] = { diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index bdedb6325c72..aa6c9f569c2b 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -131,10 +131,8 @@ struct chv_gpio_pinrange { * @ngroups: Number of groups * @functions: All functions in this community * @nfunctions: Number of functions - * @ngpios: Number of GPIOs in this community * @gpio_ranges: An array of GPIO ranges in this community * @ngpio_ranges: Number of GPIO ranges - * @ngpios: Total number of GPIOs in this community * @nirqs: Total number of IRQs this community can generate */ struct chv_community { @@ -147,7 +145,6 @@ struct chv_community { size_t nfunctions; const struct chv_gpio_pinrange *gpio_ranges; size_t ngpio_ranges; - size_t ngpios; size_t nirqs; acpi_adr_space_type acpi_space_id; }; @@ -399,7 +396,6 @@ static const struct chv_community southwest_community = { .nfunctions = ARRAY_SIZE(southwest_functions), .gpio_ranges = southwest_gpio_ranges, .ngpio_ranges = ARRAY_SIZE(southwest_gpio_ranges), - .ngpios = ARRAY_SIZE(southwest_pins), /* * Southwest community can benerate GPIO interrupts only for the * first 8 interrupts. The upper half (8-15) can only be used to @@ -489,7 +485,6 @@ static const struct chv_community north_community = { .npins = ARRAY_SIZE(north_pins), .gpio_ranges = north_gpio_ranges, .ngpio_ranges = ARRAY_SIZE(north_gpio_ranges), - .ngpios = ARRAY_SIZE(north_pins), /* * North community can generate GPIO interrupts only for the first * 8 interrupts. The upper half (8-15) can only be used to trigger @@ -538,7 +533,6 @@ static const struct chv_community east_community = { .npins = ARRAY_SIZE(east_pins), .gpio_ranges = east_gpio_ranges, .ngpio_ranges = ARRAY_SIZE(east_gpio_ranges), - .ngpios = ARRAY_SIZE(east_pins), .nirqs = 16, .acpi_space_id = 0x93, }; @@ -665,7 +659,6 @@ static const struct chv_community southeast_community = { .nfunctions = ARRAY_SIZE(southeast_functions), .gpio_ranges = southeast_gpio_ranges, .ngpio_ranges = ARRAY_SIZE(southeast_gpio_ranges), - .ngpios = ARRAY_SIZE(southeast_pins), .nirqs = 16, .acpi_space_id = 0x94, }; @@ -1253,21 +1246,14 @@ static struct pinctrl_desc chv_pinctrl_desc = { .owner = THIS_MODULE, }; -static unsigned chv_gpio_offset_to_pin(struct chv_pinctrl *pctrl, - unsigned offset) -{ - return pctrl->community->pins[offset].number; -} - static int chv_gpio_get(struct gpio_chip *chip, unsigned offset) { struct chv_pinctrl *pctrl = gpiochip_get_data(chip); - int pin = chv_gpio_offset_to_pin(pctrl, offset); unsigned long flags; u32 ctrl0, cfg; raw_spin_lock_irqsave(&chv_lock, flags); - ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); + ctrl0 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0)); raw_spin_unlock_irqrestore(&chv_lock, flags); cfg = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK; @@ -1281,14 +1267,13 @@ static int chv_gpio_get(struct gpio_chip *chip, unsigned offset) static void chv_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { struct chv_pinctrl *pctrl = gpiochip_get_data(chip); - unsigned pin = chv_gpio_offset_to_pin(pctrl, offset); unsigned long flags; void __iomem *reg; u32 ctrl0; raw_spin_lock_irqsave(&chv_lock, flags); - reg = chv_padreg(pctrl, pin, CHV_PADCTRL0); + reg = chv_padreg(pctrl, offset, CHV_PADCTRL0); ctrl0 = readl(reg); if (value) @@ -1304,12 +1289,11 @@ static void chv_gpio_set(struct gpio_chip *chip, unsigned offset, int value) static int chv_gpio_get_direction(struct gpio_chip *chip, unsigned offset) { struct chv_pinctrl *pctrl = gpiochip_get_data(chip); - unsigned pin = chv_gpio_offset_to_pin(pctrl, offset); u32 ctrl0, direction; unsigned long flags; raw_spin_lock_irqsave(&chv_lock, flags); - ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); + ctrl0 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0)); raw_spin_unlock_irqrestore(&chv_lock, flags); direction = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK; @@ -1345,7 +1329,7 @@ static void chv_gpio_irq_ack(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct chv_pinctrl *pctrl = gpiochip_get_data(gc); - int pin = chv_gpio_offset_to_pin(pctrl, irqd_to_hwirq(d)); + int pin = irqd_to_hwirq(d); u32 intr_line; raw_spin_lock(&chv_lock); @@ -1362,7 +1346,7 @@ static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct chv_pinctrl *pctrl = gpiochip_get_data(gc); - int pin = chv_gpio_offset_to_pin(pctrl, irqd_to_hwirq(d)); + int pin = irqd_to_hwirq(d); u32 value, intr_line; unsigned long flags; @@ -1407,8 +1391,7 @@ static unsigned chv_gpio_irq_startup(struct irq_data *d) if (irqd_get_trigger_type(d) == IRQ_TYPE_NONE) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct chv_pinctrl *pctrl = gpiochip_get_data(gc); - unsigned offset = irqd_to_hwirq(d); - int pin = chv_gpio_offset_to_pin(pctrl, offset); + unsigned pin = irqd_to_hwirq(d); irq_flow_handler_t handler; unsigned long flags; u32 intsel, value; @@ -1426,7 +1409,7 @@ static unsigned chv_gpio_irq_startup(struct irq_data *d) if (!pctrl->intr_lines[intsel]) { irq_set_handler_locked(d, handler); - pctrl->intr_lines[intsel] = offset; + pctrl->intr_lines[intsel] = pin; } raw_spin_unlock_irqrestore(&chv_lock, flags); } @@ -1439,8 +1422,7 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned type) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct chv_pinctrl *pctrl = gpiochip_get_data(gc); - unsigned offset = irqd_to_hwirq(d); - int pin = chv_gpio_offset_to_pin(pctrl, offset); + unsigned pin = irqd_to_hwirq(d); unsigned long flags; u32 value; @@ -1486,7 +1468,7 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned type) value &= CHV_PADCTRL0_INTSEL_MASK; value >>= CHV_PADCTRL0_INTSEL_SHIFT; - pctrl->intr_lines[value] = offset; + pctrl->intr_lines[value] = pin; if (type & IRQ_TYPE_EDGE_BOTH) irq_set_handler_locked(d, handle_edge_irq); @@ -1576,12 +1558,12 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) const struct chv_gpio_pinrange *range; struct gpio_chip *chip = &pctrl->chip; bool need_valid_mask = !dmi_check_system(chv_no_valid_mask); - int ret, i, offset; - int irq_base; + const struct chv_community *community = pctrl->community; + int ret, i, irq_base; *chip = chv_gpio_chip; - chip->ngpio = pctrl->community->ngpios; + chip->ngpio = community->pins[community->npins - 1].number + 1; chip->label = dev_name(pctrl->dev); chip->parent = pctrl->dev; chip->base = -1; @@ -1593,30 +1575,29 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) return ret; } - for (i = 0, offset = 0; i < pctrl->community->ngpio_ranges; i++) { - range = &pctrl->community->gpio_ranges[i]; - ret = gpiochip_add_pin_range(chip, dev_name(pctrl->dev), offset, - range->base, range->npins); + for (i = 0; i < community->ngpio_ranges; i++) { + range = &community->gpio_ranges[i]; + ret = gpiochip_add_pin_range(chip, dev_name(pctrl->dev), + range->base, range->base, + range->npins); if (ret) { dev_err(pctrl->dev, "failed to add GPIO pin range\n"); return ret; } - - offset += range->npins; } /* Do not add GPIOs that can only generate GPEs to the IRQ domain */ - for (i = 0; i < pctrl->community->npins; i++) { + for (i = 0; i < community->npins; i++) { const struct pinctrl_pin_desc *desc; u32 intsel; - desc = &pctrl->community->pins[i]; + desc = &community->pins[i]; intsel = readl(chv_padreg(pctrl, desc->number, CHV_PADCTRL0)); intsel &= CHV_PADCTRL0_INTSEL_MASK; intsel >>= CHV_PADCTRL0_INTSEL_SHIFT; - if (need_valid_mask && intsel >= pctrl->community->nirqs) + if (need_valid_mask && intsel >= community->nirqs) clear_bit(i, chip->irq.valid_mask); } diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 12a1af45acb9..96e73e30204e 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -425,6 +425,18 @@ static void __intel_gpio_set_direction(void __iomem *padcfg0, bool input) writel(value, padcfg0); } +static void intel_gpio_set_gpio_mode(void __iomem *padcfg0) +{ + u32 value; + + /* Put the pad into GPIO mode */ + value = readl(padcfg0) & ~PADCFG0_PMODE_MASK; + /* Disable SCI/SMI/NMI generation */ + value &= ~(PADCFG0_GPIROUTIOXAPIC | PADCFG0_GPIROUTSCI); + value &= ~(PADCFG0_GPIROUTSMI | PADCFG0_GPIROUTNMI); + writel(value, padcfg0); +} + static int intel_gpio_request_enable(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned pin) @@ -432,7 +444,6 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev, struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); void __iomem *padcfg0; unsigned long flags; - u32 value; raw_spin_lock_irqsave(&pctrl->lock, flags); @@ -442,13 +453,7 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev, } padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0); - /* Put the pad into GPIO mode */ - value = readl(padcfg0) & ~PADCFG0_PMODE_MASK; - /* Disable SCI/SMI/NMI generation */ - value &= ~(PADCFG0_GPIROUTIOXAPIC | PADCFG0_GPIROUTSCI); - value &= ~(PADCFG0_GPIROUTSMI | PADCFG0_GPIROUTNMI); - writel(value, padcfg0); - + intel_gpio_set_gpio_mode(padcfg0); /* Disable TX buffer and enable RX (this will be input) */ __intel_gpio_set_direction(padcfg0, true); @@ -806,22 +811,63 @@ static const struct gpio_chip intel_gpio_chip = { .set_config = gpiochip_generic_config, }; +/** + * intel_gpio_to_pin() - Translate from GPIO offset to pin number + * @pctrl: Pinctrl structure + * @offset: GPIO offset from gpiolib + * @commmunity: Community is filled here if not %NULL + * @padgrp: Pad group is filled here if not %NULL + * + * When coming through gpiolib irqchip, the GPIO offset is not + * automatically translated to pinctrl pin number. This function can be + * used to find out the corresponding pinctrl pin. + */ +static int intel_gpio_to_pin(struct intel_pinctrl *pctrl, unsigned offset, + const struct intel_community **community, + const struct intel_padgroup **padgrp) +{ + int i; + + for (i = 0; i < pctrl->ncommunities; i++) { + const struct intel_community *comm = &pctrl->communities[i]; + int j; + + for (j = 0; j < comm->ngpps; j++) { + const struct intel_padgroup *pgrp = &comm->gpps[j]; + + if (pgrp->gpio_base < 0) + continue; + + if (offset >= pgrp->gpio_base && + offset < pgrp->gpio_base + pgrp->size) { + int pin; + + pin = pgrp->base + offset - pgrp->gpio_base; + if (community) + *community = comm; + if (padgrp) + *padgrp = pgrp; + + return pin; + } + } + } + + return -EINVAL; +} + static void intel_gpio_irq_ack(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct intel_pinctrl *pctrl = gpiochip_get_data(gc); const struct intel_community *community; - unsigned pin = irqd_to_hwirq(d); + const struct intel_padgroup *padgrp; + int pin; - community = intel_get_community(pctrl, pin); - if (community) { - const struct intel_padgroup *padgrp; + pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), &community, &padgrp); + if (pin >= 0) { unsigned gpp, gpp_offset, is_offset; - padgrp = intel_community_get_padgroup(community, pin); - if (!padgrp) - return; - gpp = padgrp->reg_num; gpp_offset = padgroup_offset(padgrp, pin); is_offset = community->is_offset + gpp * 4; @@ -837,19 +883,15 @@ static void intel_gpio_irq_enable(struct irq_data *d) struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct intel_pinctrl *pctrl = gpiochip_get_data(gc); const struct intel_community *community; - unsigned pin = irqd_to_hwirq(d); + const struct intel_padgroup *padgrp; + int pin; - community = intel_get_community(pctrl, pin); - if (community) { - const struct intel_padgroup *padgrp; + pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), &community, &padgrp); + if (pin >= 0) { unsigned gpp, gpp_offset, is_offset; unsigned long flags; u32 value; - padgrp = intel_community_get_padgroup(community, pin); - if (!padgrp) - return; - gpp = padgrp->reg_num; gpp_offset = padgroup_offset(padgrp, pin); is_offset = community->is_offset + gpp * 4; @@ -870,20 +912,16 @@ static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask) struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct intel_pinctrl *pctrl = gpiochip_get_data(gc); const struct intel_community *community; - unsigned pin = irqd_to_hwirq(d); + const struct intel_padgroup *padgrp; + int pin; - community = intel_get_community(pctrl, pin); - if (community) { - const struct intel_padgroup *padgrp; + pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), &community, &padgrp); + if (pin >= 0) { unsigned gpp, gpp_offset; unsigned long flags; void __iomem *reg; u32 value; - padgrp = intel_community_get_padgroup(community, pin); - if (!padgrp) - return; - gpp = padgrp->reg_num; gpp_offset = padgroup_offset(padgrp, pin); @@ -914,7 +952,7 @@ static int intel_gpio_irq_type(struct irq_data *d, unsigned type) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct intel_pinctrl *pctrl = gpiochip_get_data(gc); - unsigned pin = irqd_to_hwirq(d); + unsigned pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), NULL, NULL); unsigned long flags; void __iomem *reg; u32 value; @@ -935,6 +973,8 @@ static int intel_gpio_irq_type(struct irq_data *d, unsigned type) raw_spin_lock_irqsave(&pctrl->lock, flags); + intel_gpio_set_gpio_mode(reg); + value = readl(reg); value &= ~(PADCFG0_RXEVCFG_MASK | PADCFG0_RXINV); @@ -969,7 +1009,7 @@ static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct intel_pinctrl *pctrl = gpiochip_get_data(gc); - unsigned pin = irqd_to_hwirq(d); + unsigned pin = intel_gpio_to_pin(pctrl, irqd_to_hwirq(d), NULL, NULL); if (on) enable_irq_wake(pctrl->irq); @@ -1000,14 +1040,10 @@ static irqreturn_t intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl, pending &= enabled; for_each_set_bit(gpp_offset, &pending, padgrp->size) { - unsigned padno, irq; - - padno = padgrp->base - community->pin_base + gpp_offset; - if (padno >= community->npins) - break; + unsigned irq; irq = irq_find_mapping(gc->irq.domain, - community->pin_base + padno); + padgrp->gpio_base + gpp_offset); generic_handle_irq(irq); ret |= IRQ_HANDLED; @@ -1044,13 +1080,56 @@ static struct irq_chip intel_gpio_irqchip = { .flags = IRQCHIP_MASK_ON_SUSPEND, }; +static int intel_gpio_add_pin_ranges(struct intel_pinctrl *pctrl, + const struct intel_community *community) +{ + int ret = 0, i; + + for (i = 0; i < community->ngpps; i++) { + const struct intel_padgroup *gpp = &community->gpps[i]; + + if (gpp->gpio_base < 0) + continue; + + ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev), + gpp->gpio_base, gpp->base, + gpp->size); + if (ret) + return ret; + } + + return ret; +} + +static unsigned intel_gpio_ngpio(const struct intel_pinctrl *pctrl) +{ + const struct intel_community *community; + unsigned ngpio = 0; + int i, j; + + for (i = 0; i < pctrl->ncommunities; i++) { + community = &pctrl->communities[i]; + for (j = 0; j < community->ngpps; j++) { + const struct intel_padgroup *gpp = &community->gpps[j]; + + if (gpp->gpio_base < 0) + continue; + + if (gpp->gpio_base + gpp->size > ngpio) + ngpio = gpp->gpio_base + gpp->size; + } + } + + return ngpio; +} + static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq) { - int ret; + int ret, i; pctrl->chip = intel_gpio_chip; - pctrl->chip.ngpio = pctrl->soc->npins; + pctrl->chip.ngpio = intel_gpio_ngpio(pctrl); pctrl->chip.label = dev_name(pctrl->dev); pctrl->chip.parent = pctrl->dev; pctrl->chip.base = -1; @@ -1062,11 +1141,14 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq) return ret; } - ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev), - 0, 0, pctrl->soc->npins); - if (ret) { - dev_err(pctrl->dev, "failed to add GPIO pin range\n"); - return ret; + for (i = 0; i < pctrl->ncommunities; i++) { + struct intel_community *community = &pctrl->communities[i]; + + ret = intel_gpio_add_pin_ranges(pctrl, community); + if (ret) { + dev_err(pctrl->dev, "failed to add GPIO pin range\n"); + return ret; + } } /* @@ -1126,6 +1208,9 @@ static int intel_pinctrl_add_padgroups(struct intel_pinctrl *pctrl, if (gpps[i].size > 32) return -EINVAL; + if (!gpps[i].gpio_base) + gpps[i].gpio_base = gpps[i].base; + gpps[i].padown_num = padown_num; /* diff --git a/drivers/pinctrl/intel/pinctrl-intel.h b/drivers/pinctrl/intel/pinctrl-intel.h index 13b0bd6eb2a2..98fdf9adf623 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.h +++ b/drivers/pinctrl/intel/pinctrl-intel.h @@ -51,6 +51,8 @@ struct intel_function { * @reg_num: GPI_IS register number * @base: Starting pin of this group * @size: Size of this group (maximum is 32). + * @gpio_base: Starting GPIO base of this group (%0 if matches with @base, + * and %-1 if no GPIO mapping should be created) * @padown_num: PAD_OWN register number (assigned by the core driver) * * If pad groups of a community are not the same size, use this structure @@ -60,6 +62,7 @@ struct intel_padgroup { unsigned reg_num; unsigned base; unsigned size; + int gpio_base; unsigned padown_num; }; diff --git a/drivers/pinctrl/intel/pinctrl-merrifield.c b/drivers/pinctrl/intel/pinctrl-merrifield.c index 86c4b3fab7b0..d9357054d41d 100644 --- a/drivers/pinctrl/intel/pinctrl-merrifield.c +++ b/drivers/pinctrl/intel/pinctrl-merrifield.c @@ -931,10 +931,17 @@ static int mrfld_pinctrl_probe(struct platform_device *pdev) return 0; } +static const struct acpi_device_id mrfld_acpi_table[] = { + { "INTC1002" }, + { } +}; +MODULE_DEVICE_TABLE(acpi, mrfld_acpi_table); + static struct platform_driver mrfld_pinctrl_driver = { .probe = mrfld_pinctrl_probe, .driver = { .name = "pinctrl-merrifield", + .acpi_match_table = mrfld_acpi_table, }, }; diff --git a/drivers/pinctrl/meson/Kconfig b/drivers/pinctrl/meson/Kconfig index 1a51778759ea..c80951d6caff 100644 --- a/drivers/pinctrl/meson/Kconfig +++ b/drivers/pinctrl/meson/Kconfig @@ -38,4 +38,13 @@ config PINCTRL_MESON_GXL config PINCTRL_MESON8_PMX bool +config PINCTRL_MESON_AXG + bool "Meson axg Soc pinctrl driver" + depends on ARM64 + select PINCTRL_MESON_AXG_PMX + default y + +config PINCTRL_MESON_AXG_PMX + bool + endif diff --git a/drivers/pinctrl/meson/Makefile b/drivers/pinctrl/meson/Makefile index cbd47bb74549..3c6580c2d9d7 100644 --- a/drivers/pinctrl/meson/Makefile +++ b/drivers/pinctrl/meson/Makefile @@ -4,3 +4,5 @@ obj-$(CONFIG_PINCTRL_MESON8) += pinctrl-meson8.o obj-$(CONFIG_PINCTRL_MESON8B) += pinctrl-meson8b.o obj-$(CONFIG_PINCTRL_MESON_GXBB) += pinctrl-meson-gxbb.o obj-$(CONFIG_PINCTRL_MESON_GXL) += pinctrl-meson-gxl.o +obj-$(CONFIG_PINCTRL_MESON_AXG_PMX) += pinctrl-meson-axg-pmx.o +obj-$(CONFIG_PINCTRL_MESON_AXG) += pinctrl-meson-axg.o diff --git a/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c b/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c new file mode 100644 index 000000000000..e8931d9cf863 --- /dev/null +++ b/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c @@ -0,0 +1,118 @@ +/* + * Second generation of pinmux driver for Amlogic Meson-AXG SoC. + * + * Copyright (c) 2017 Baylibre SAS. + * Author: Jerome Brunet <jbrunet@baylibre.com> + * + * Copyright (c) 2017 Amlogic, Inc. All rights reserved. + * Author: Xingyu Chen <xingyu.chen@amlogic.com> + * + * SPDX-License-Identifier: (GPL-2.0+ or MIT) + */ + +/* + * This new generation of pinctrl IP is mainly adopted by the + * Meson-AXG SoC and later series, which use 4-width continuous + * register bit to select the function for each pin. + * + * The value 0 is always selecting the GPIO mode, while other + * values (start from 1) for selecting the function mode. + */ +#include <linux/device.h> +#include <linux/regmap.h> +#include <linux/pinctrl/pinctrl.h> +#include <linux/pinctrl/pinmux.h> + +#include "pinctrl-meson.h" +#include "pinctrl-meson-axg-pmx.h" + +static int meson_axg_pmx_get_bank(struct meson_pinctrl *pc, + unsigned int pin, + struct meson_pmx_bank **bank) +{ + int i; + struct meson_axg_pmx_data *pmx = pc->data->pmx_data; + + for (i = 0; i < pmx->num_pmx_banks; i++) + if (pin >= pmx->pmx_banks[i].first && + pin <= pmx->pmx_banks[i].last) { + *bank = &pmx->pmx_banks[i]; + return 0; + } + + return -EINVAL; +} + +static int meson_pmx_calc_reg_and_offset(struct meson_pmx_bank *bank, + unsigned int pin, unsigned int *reg, + unsigned int *offset) +{ + int shift; + + shift = pin - bank->first; + + *reg = bank->reg + (bank->offset + (shift << 2)) / 32; + *offset = (bank->offset + (shift << 2)) % 32; + + return 0; +} + +static int meson_axg_pmx_update_function(struct meson_pinctrl *pc, + unsigned int pin, unsigned int func) +{ + int ret; + int reg; + int offset; + struct meson_pmx_bank *bank; + + ret = meson_axg_pmx_get_bank(pc, pin, &bank); + if (ret) + return ret; + + meson_pmx_calc_reg_and_offset(bank, pin, ®, &offset); + + ret = regmap_update_bits(pc->reg_mux, reg << 2, + 0xf << offset, (func & 0xf) << offset); + + return ret; +} + +static int meson_axg_pmx_set_mux(struct pinctrl_dev *pcdev, + unsigned int func_num, unsigned int group_num) +{ + int i; + int ret; + struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev); + struct meson_pmx_func *func = &pc->data->funcs[func_num]; + struct meson_pmx_group *group = &pc->data->groups[group_num]; + struct meson_pmx_axg_data *pmx_data = + (struct meson_pmx_axg_data *)group->data; + + dev_dbg(pc->dev, "enable function %s, group %s\n", func->name, + group->name); + + for (i = 0; i < group->num_pins; i++) { + ret = meson_axg_pmx_update_function(pc, group->pins[i], + pmx_data->func); + if (ret) + return ret; + } + + return 0; +} + +static int meson_axg_pmx_request_gpio(struct pinctrl_dev *pcdev, + struct pinctrl_gpio_range *range, unsigned int offset) +{ + struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev); + + return meson_axg_pmx_update_function(pc, offset, 0); +} + +const struct pinmux_ops meson_axg_pmx_ops = { + .set_mux = meson_axg_pmx_set_mux, + .get_functions_count = meson_pmx_get_funcs_count, + .get_function_name = meson_pmx_get_func_name, + .get_function_groups = meson_pmx_get_groups, + .gpio_request_enable = meson_axg_pmx_request_gpio, +}; diff --git a/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.h b/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.h new file mode 100644 index 000000000000..8ff88bf2e849 --- /dev/null +++ b/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2017 Baylibre SAS. + * Author: Jerome Brunet <jbrunet@baylibre.com> + * + * Copyright (c) 2017 Amlogic, Inc. All rights reserved. + * Author: Xingyu Chen <xingyu.chen@amlogic.com> + * + * SPDX-License-Identifier: (GPL-2.0+ or MIT) + */ + +struct meson_pmx_bank { + const char *name; + unsigned int first; + unsigned int last; + unsigned int reg; + unsigned int offset; +}; + +struct meson_axg_pmx_data { + struct meson_pmx_bank *pmx_banks; + unsigned int num_pmx_banks; +}; + +#define BANK_PMX(n, f, l, r, o) \ + { \ + .name = n, \ + .first = f, \ + .last = l, \ + .reg = r, \ + .offset = o, \ + } + +struct meson_pmx_axg_data { + unsigned int func; +}; + +#define PMX_DATA(f) \ + { \ + .func = f, \ + } + +#define GROUP(grp, f) \ + { \ + .name = #grp, \ + .pins = grp ## _pins, \ + .num_pins = ARRAY_SIZE(grp ## _pins), \ + .data = (const struct meson_pmx_axg_data[]){ \ + PMX_DATA(f), \ + }, \ + } + +#define GPIO_GROUP(gpio) \ + { \ + .name = #gpio, \ + .pins = (const unsigned int[]){ gpio }, \ + .num_pins = 1, \ + .data = (const struct meson_pmx_axg_data[]){ \ + PMX_DATA(0), \ + }, \ + } + +extern const struct pinmux_ops meson_axg_pmx_ops; diff --git a/drivers/pinctrl/meson/pinctrl-meson-axg.c b/drivers/pinctrl/meson/pinctrl-meson-axg.c new file mode 100644 index 000000000000..a1a7d42afd42 --- /dev/null +++ b/drivers/pinctrl/meson/pinctrl-meson-axg.c @@ -0,0 +1,975 @@ +/* + * Pin controller and GPIO driver for Amlogic Meson AXG SoC. + * + * Copyright (c) 2017 Amlogic, Inc. All rights reserved. + * Author: Xingyu Chen <xingyu.chen@amlogic.com> + * + * SPDX-License-Identifier: (GPL-2.0+ or MIT) + */ + +#include <dt-bindings/gpio/meson-axg-gpio.h> +#include "pinctrl-meson.h" +#include "pinctrl-meson-axg-pmx.h" + +static const struct pinctrl_pin_desc meson_axg_periphs_pins[] = { + MESON_PIN(GPIOZ_0), + MESON_PIN(GPIOZ_1), + MESON_PIN(GPIOZ_2), + MESON_PIN(GPIOZ_3), + MESON_PIN(GPIOZ_4), + MESON_PIN(GPIOZ_5), + MESON_PIN(GPIOZ_6), + MESON_PIN(GPIOZ_7), + MESON_PIN(GPIOZ_8), + MESON_PIN(GPIOZ_9), + MESON_PIN(GPIOZ_10), + MESON_PIN(BOOT_0), + MESON_PIN(BOOT_1), + MESON_PIN(BOOT_2), + MESON_PIN(BOOT_3), + MESON_PIN(BOOT_4), + MESON_PIN(BOOT_5), + MESON_PIN(BOOT_6), + MESON_PIN(BOOT_7), + MESON_PIN(BOOT_8), + MESON_PIN(BOOT_9), + MESON_PIN(BOOT_10), + MESON_PIN(BOOT_11), + MESON_PIN(BOOT_12), + MESON_PIN(BOOT_13), + MESON_PIN(BOOT_14), + MESON_PIN(GPIOA_0), + MESON_PIN(GPIOA_1), + MESON_PIN(GPIOA_2), + MESON_PIN(GPIOA_3), + MESON_PIN(GPIOA_4), + MESON_PIN(GPIOA_5), + MESON_PIN(GPIOA_6), + MESON_PIN(GPIOA_7), + MESON_PIN(GPIOA_8), + MESON_PIN(GPIOA_9), + MESON_PIN(GPIOA_10), + MESON_PIN(GPIOA_11), + MESON_PIN(GPIOA_12), + MESON_PIN(GPIOA_13), + MESON_PIN(GPIOA_14), + MESON_PIN(GPIOA_15), + MESON_PIN(GPIOA_16), + MESON_PIN(GPIOA_17), + MESON_PIN(GPIOA_18), + MESON_PIN(GPIOA_19), + MESON_PIN(GPIOA_20), + MESON_PIN(GPIOX_0), + MESON_PIN(GPIOX_1), + MESON_PIN(GPIOX_2), + MESON_PIN(GPIOX_3), + MESON_PIN(GPIOX_4), + MESON_PIN(GPIOX_5), + MESON_PIN(GPIOX_6), + MESON_PIN(GPIOX_7), + MESON_PIN(GPIOX_8), + MESON_PIN(GPIOX_9), + MESON_PIN(GPIOX_10), + MESON_PIN(GPIOX_11), + MESON_PIN(GPIOX_12), + MESON_PIN(GPIOX_13), + MESON_PIN(GPIOX_14), + MESON_PIN(GPIOX_15), + MESON_PIN(GPIOX_16), + MESON_PIN(GPIOX_17), + MESON_PIN(GPIOX_18), + MESON_PIN(GPIOX_19), + MESON_PIN(GPIOX_20), + MESON_PIN(GPIOX_21), + MESON_PIN(GPIOX_22), + MESON_PIN(GPIOY_0), + MESON_PIN(GPIOY_1), + MESON_PIN(GPIOY_2), + MESON_PIN(GPIOY_3), + MESON_PIN(GPIOY_4), + MESON_PIN(GPIOY_5), + MESON_PIN(GPIOY_6), + MESON_PIN(GPIOY_7), + MESON_PIN(GPIOY_8), + MESON_PIN(GPIOY_9), + MESON_PIN(GPIOY_10), + MESON_PIN(GPIOY_11), + MESON_PIN(GPIOY_12), + MESON_PIN(GPIOY_13), + MESON_PIN(GPIOY_14), + MESON_PIN(GPIOY_15), +}; + +static const struct pinctrl_pin_desc meson_axg_aobus_pins[] = { + MESON_PIN(GPIOAO_0), + MESON_PIN(GPIOAO_1), + MESON_PIN(GPIOAO_2), + MESON_PIN(GPIOAO_3), + MESON_PIN(GPIOAO_4), + MESON_PIN(GPIOAO_5), + MESON_PIN(GPIOAO_6), + MESON_PIN(GPIOAO_7), + MESON_PIN(GPIOAO_8), + MESON_PIN(GPIOAO_9), + MESON_PIN(GPIOAO_10), + MESON_PIN(GPIOAO_11), + MESON_PIN(GPIOAO_12), + MESON_PIN(GPIOAO_13), + MESON_PIN(GPIO_TEST_N), +}; + +/* emmc */ +static const unsigned int emmc_nand_d0_pins[] = {BOOT_0}; +static const unsigned int emmc_nand_d1_pins[] = {BOOT_1}; +static const unsigned int emmc_nand_d2_pins[] = {BOOT_2}; +static const unsigned int emmc_nand_d3_pins[] = {BOOT_3}; +static const unsigned int emmc_nand_d4_pins[] = {BOOT_4}; +static const unsigned int emmc_nand_d5_pins[] = {BOOT_5}; +static const unsigned int emmc_nand_d6_pins[] = {BOOT_6}; +static const unsigned int emmc_nand_d7_pins[] = {BOOT_7}; + +static const unsigned int emmc_clk_pins[] = {BOOT_8}; +static const unsigned int emmc_cmd_pins[] = {BOOT_10}; +static const unsigned int emmc_ds_pins[] = {BOOT_13}; + +/* nand */ +static const unsigned int nand_ce0_pins[] = {BOOT_8}; +static const unsigned int nand_ale_pins[] = {BOOT_9}; +static const unsigned int nand_cle_pins[] = {BOOT_10}; +static const unsigned int nand_wen_clk_pins[] = {BOOT_11}; +static const unsigned int nand_ren_wr_pins[] = {BOOT_12}; +static const unsigned int nand_rb0_pins[] = {BOOT_13}; + +/* nor */ +static const unsigned int nor_hold_pins[] = {BOOT_3}; +static const unsigned int nor_d_pins[] = {BOOT_4}; +static const unsigned int nor_q_pins[] = {BOOT_5}; +static const unsigned int nor_c_pins[] = {BOOT_6}; +static const unsigned int nor_wp_pins[] = {BOOT_9}; +static const unsigned int nor_cs_pins[] = {BOOT_14}; + +/* sdio */ +static const unsigned int sdio_d0_pins[] = {GPIOX_0}; +static const unsigned int sdio_d1_pins[] = {GPIOX_1}; +static const unsigned int sdio_d2_pins[] = {GPIOX_2}; +static const unsigned int sdio_d3_pins[] = {GPIOX_3}; +static const unsigned int sdio_clk_pins[] = {GPIOX_4}; +static const unsigned int sdio_cmd_pins[] = {GPIOX_5}; + +/* spi_a */ +static const unsigned int spi_clk_a_pins[] = {GPIOZ_0}; +static const unsigned int spi_mosi_a_pins[] = {GPIOZ_1}; +static const unsigned int spi_miso_a_pins[] = {GPIOZ_2}; +static const unsigned int spi_ss0_a_pins[] = {GPIOZ_3}; +static const unsigned int spi_ss1_a_pins[] = {GPIOZ_4}; +static const unsigned int spi_ss2_a_pins[] = {GPIOZ_5}; + +/* spi_b */ +static const unsigned int spi_clk_b_x_pins[] = {GPIOX_19}; +static const unsigned int spi_mosi_b_x_pins[] = {GPIOX_17}; +static const unsigned int spi_miso_b_x_pins[] = {GPIOX_18}; +static const unsigned int spi_ss0_b_x_pins[] = {GPIOX_16}; + +static const unsigned int spi_clk_b_a_pins[] = {GPIOA_4}; +static const unsigned int spi_mosi_b_a_pins[] = {GPIOA_2}; +static const unsigned int spi_miso_b_a_pins[] = {GPIOA_3}; +static const unsigned int spi_ss0_b_a_pins[] = {GPIOA_5}; +static const unsigned int spi_ss1_b_pins[] = {GPIOA_6}; + +/* i2c0 */ +static const unsigned int i2c0_sck_pins[] = {GPIOZ_6}; +static const unsigned int i2c0_sda_pins[] = {GPIOZ_7}; + +/* i2c1 */ +static const unsigned int i2c1_sck_z_pins[] = {GPIOZ_8}; +static const unsigned int i2c1_sda_z_pins[] = {GPIOZ_9}; + +static const unsigned int i2c1_sck_x_pins[] = {GPIOX_16}; +static const unsigned int i2c1_sda_x_pins[] = {GPIOX_17}; + +/* i2c2 */ +static const unsigned int i2c2_sck_x_pins[] = {GPIOX_18}; +static const unsigned int i2c2_sda_x_pins[] = {GPIOX_19}; + +static const unsigned int i2c2_sda_a_pins[] = {GPIOA_17}; +static const unsigned int i2c2_sck_a_pins[] = {GPIOA_18}; + +/* i2c3 */ +static const unsigned int i2c3_sda_a6_pins[] = {GPIOA_6}; +static const unsigned int i2c3_sck_a7_pins[] = {GPIOA_7}; + +static const unsigned int i2c3_sda_a12_pins[] = {GPIOA_12}; +static const unsigned int i2c3_sck_a13_pins[] = {GPIOA_13}; + +static const unsigned int i2c3_sda_a19_pins[] = {GPIOA_19}; +static const unsigned int i2c3_sck_a20_pins[] = {GPIOA_20}; + +/* uart_a */ +static const unsigned int uart_rts_a_pins[] = {GPIOX_11}; +static const unsigned int uart_cts_a_pins[] = {GPIOX_10}; +static const unsigned int uart_tx_a_pins[] = {GPIOX_8}; +static const unsigned int uart_rx_a_pins[] = {GPIOX_9}; + +/* uart_b */ +static const unsigned int uart_rts_b_z_pins[] = {GPIOZ_0}; +static const unsigned int uart_cts_b_z_pins[] = {GPIOZ_1}; +static const unsigned int uart_tx_b_z_pins[] = {GPIOZ_2}; +static const unsigned int uart_rx_b_z_pins[] = {GPIOZ_3}; + +static const unsigned int uart_rts_b_x_pins[] = {GPIOX_18}; +static const unsigned int uart_cts_b_x_pins[] = {GPIOX_19}; +static const unsigned int uart_tx_b_x_pins[] = {GPIOX_16}; +static const unsigned int uart_rx_b_x_pins[] = {GPIOX_17}; + +/* uart_ao_b */ +static const unsigned int uart_ao_tx_b_z_pins[] = {GPIOZ_8}; +static const unsigned int uart_ao_rx_b_z_pins[] = {GPIOZ_9}; +static const unsigned int uart_ao_cts_b_z_pins[] = {GPIOZ_6}; +static const unsigned int uart_ao_rts_b_z_pins[] = {GPIOZ_7}; + +/* pwm_a */ +static const unsigned int pwm_a_z_pins[] = {GPIOZ_5}; + +static const unsigned int pwm_a_x18_pins[] = {GPIOX_18}; +static const unsigned int pwm_a_x20_pins[] = {GPIOX_20}; + +static const unsigned int pwm_a_a_pins[] = {GPIOA_14}; + +/* pwm_b */ +static const unsigned int pwm_b_z_pins[] = {GPIOZ_4}; + +static const unsigned int pwm_b_x_pins[] = {GPIOX_19}; + +static const unsigned int pwm_b_a_pins[] = {GPIOA_15}; + +/* pwm_c */ +static const unsigned int pwm_c_x10_pins[] = {GPIOX_10}; +static const unsigned int pwm_c_x17_pins[] = {GPIOX_17}; + +static const unsigned int pwm_c_a_pins[] = {GPIOA_16}; + +/* pwm_d */ +static const unsigned int pwm_d_x11_pins[] = {GPIOX_11}; +static const unsigned int pwm_d_x16_pins[] = {GPIOX_16}; + +/* pwm_vs */ +static const unsigned int pwm_vs_pins[] = {GPIOA_0}; + +/* spdif_in */ +static const unsigned int spdif_in_z_pins[] = {GPIOZ_4}; + +static const unsigned int spdif_in_a1_pins[] = {GPIOA_1}; +static const unsigned int spdif_in_a7_pins[] = {GPIOA_7}; +static const unsigned int spdif_in_a19_pins[] = {GPIOA_19}; +static const unsigned int spdif_in_a20_pins[] = {GPIOA_20}; + +/* spdif_out */ +static const unsigned int spdif_out_z_pins[] = {GPIOZ_5}; + +static const unsigned int spdif_out_a1_pins[] = {GPIOA_1}; +static const unsigned int spdif_out_a11_pins[] = {GPIOA_11}; +static const unsigned int spdif_out_a19_pins[] = {GPIOA_19}; +static const unsigned int spdif_out_a20_pins[] = {GPIOA_20}; + +/* jtag_ee */ +static const unsigned int jtag_tdo_x_pins[] = {GPIOX_0}; +static const unsigned int jtag_tdi_x_pins[] = {GPIOX_1}; +static const unsigned int jtag_clk_x_pins[] = {GPIOX_4}; +static const unsigned int jtag_tms_x_pins[] = {GPIOX_5}; + +/* eth */ +static const unsigned int eth_txd0_x_pins[] = {GPIOX_8}; +static const unsigned int eth_txd1_x_pins[] = {GPIOX_9}; +static const unsigned int eth_txen_x_pins[] = {GPIOX_10}; +static const unsigned int eth_rgmii_rx_clk_x_pins[] = {GPIOX_12}; +static const unsigned int eth_rxd0_x_pins[] = {GPIOX_13}; +static const unsigned int eth_rxd1_x_pins[] = {GPIOX_14}; +static const unsigned int eth_rx_dv_x_pins[] = {GPIOX_15}; +static const unsigned int eth_mdio_x_pins[] = {GPIOX_21}; +static const unsigned int eth_mdc_x_pins[] = {GPIOX_22}; + +static const unsigned int eth_txd0_y_pins[] = {GPIOY_10}; +static const unsigned int eth_txd1_y_pins[] = {GPIOY_11}; +static const unsigned int eth_txen_y_pins[] = {GPIOY_9}; +static const unsigned int eth_rgmii_rx_clk_y_pins[] = {GPIOY_2}; +static const unsigned int eth_rxd0_y_pins[] = {GPIOY_4}; +static const unsigned int eth_rxd1_y_pins[] = {GPIOY_5}; +static const unsigned int eth_rx_dv_y_pins[] = {GPIOY_3}; +static const unsigned int eth_mdio_y_pins[] = {GPIOY_0}; +static const unsigned int eth_mdc_y_pins[] = {GPIOY_1}; + +static const unsigned int eth_rxd2_rgmii_pins[] = {GPIOY_6}; +static const unsigned int eth_rxd3_rgmii_pins[] = {GPIOY_7}; +static const unsigned int eth_rgmii_tx_clk_pins[] = {GPIOY_8}; +static const unsigned int eth_txd2_rgmii_pins[] = {GPIOY_12}; +static const unsigned int eth_txd3_rgmii_pins[] = {GPIOY_13}; + +/* pdm */ +static const unsigned int pdm_dclk_a14_pins[] = {GPIOA_14}; +static const unsigned int pdm_dclk_a19_pins[] = {GPIOA_19}; +static const unsigned int pdm_din0_pins[] = {GPIOA_15}; +static const unsigned int pdm_din1_pins[] = {GPIOA_16}; +static const unsigned int pdm_din2_pins[] = {GPIOA_17}; +static const unsigned int pdm_din3_pins[] = {GPIOA_18}; + +static struct meson_pmx_group meson_axg_periphs_groups[] = { + GPIO_GROUP(GPIOZ_0), + GPIO_GROUP(GPIOZ_1), + GPIO_GROUP(GPIOZ_2), + GPIO_GROUP(GPIOZ_3), + GPIO_GROUP(GPIOZ_4), + GPIO_GROUP(GPIOZ_5), + GPIO_GROUP(GPIOZ_6), + GPIO_GROUP(GPIOZ_7), + GPIO_GROUP(GPIOZ_8), + GPIO_GROUP(GPIOZ_9), + GPIO_GROUP(GPIOZ_10), + + GPIO_GROUP(BOOT_0), + GPIO_GROUP(BOOT_1), + GPIO_GROUP(BOOT_2), + GPIO_GROUP(BOOT_3), + GPIO_GROUP(BOOT_4), + GPIO_GROUP(BOOT_5), + GPIO_GROUP(BOOT_6), + GPIO_GROUP(BOOT_7), + GPIO_GROUP(BOOT_8), + GPIO_GROUP(BOOT_9), + GPIO_GROUP(BOOT_10), + GPIO_GROUP(BOOT_11), + GPIO_GROUP(BOOT_12), + GPIO_GROUP(BOOT_13), + GPIO_GROUP(BOOT_14), + + GPIO_GROUP(GPIOA_0), + GPIO_GROUP(GPIOA_1), + GPIO_GROUP(GPIOA_2), + GPIO_GROUP(GPIOA_3), + GPIO_GROUP(GPIOA_4), + GPIO_GROUP(GPIOA_5), + GPIO_GROUP(GPIOA_6), + GPIO_GROUP(GPIOA_7), + GPIO_GROUP(GPIOA_8), + GPIO_GROUP(GPIOA_9), + GPIO_GROUP(GPIOA_10), + GPIO_GROUP(GPIOA_11), + GPIO_GROUP(GPIOA_12), + GPIO_GROUP(GPIOA_13), + GPIO_GROUP(GPIOA_14), + GPIO_GROUP(GPIOA_15), + GPIO_GROUP(GPIOA_16), + GPIO_GROUP(GPIOA_17), + GPIO_GROUP(GPIOA_19), + GPIO_GROUP(GPIOA_20), + + GPIO_GROUP(GPIOX_0), + GPIO_GROUP(GPIOX_1), + GPIO_GROUP(GPIOX_2), + GPIO_GROUP(GPIOX_3), + GPIO_GROUP(GPIOX_4), + GPIO_GROUP(GPIOX_5), + GPIO_GROUP(GPIOX_6), + GPIO_GROUP(GPIOX_7), + GPIO_GROUP(GPIOX_8), + GPIO_GROUP(GPIOX_9), + GPIO_GROUP(GPIOX_10), + GPIO_GROUP(GPIOX_11), + GPIO_GROUP(GPIOX_12), + GPIO_GROUP(GPIOX_13), + GPIO_GROUP(GPIOX_14), + GPIO_GROUP(GPIOX_15), + GPIO_GROUP(GPIOX_16), + GPIO_GROUP(GPIOX_17), + GPIO_GROUP(GPIOX_18), + GPIO_GROUP(GPIOX_19), + GPIO_GROUP(GPIOX_20), + GPIO_GROUP(GPIOX_21), + GPIO_GROUP(GPIOX_22), + + GPIO_GROUP(GPIOY_0), + GPIO_GROUP(GPIOY_1), + GPIO_GROUP(GPIOY_2), + GPIO_GROUP(GPIOY_3), + GPIO_GROUP(GPIOY_4), + GPIO_GROUP(GPIOY_5), + GPIO_GROUP(GPIOY_6), + GPIO_GROUP(GPIOY_7), + GPIO_GROUP(GPIOY_8), + GPIO_GROUP(GPIOY_9), + GPIO_GROUP(GPIOY_10), + GPIO_GROUP(GPIOY_11), + GPIO_GROUP(GPIOY_12), + GPIO_GROUP(GPIOY_13), + GPIO_GROUP(GPIOY_14), + GPIO_GROUP(GPIOY_15), + + /* bank BOOT */ + GROUP(emmc_nand_d0, 1), + GROUP(emmc_nand_d1, 1), + GROUP(emmc_nand_d2, 1), + GROUP(emmc_nand_d3, 1), + GROUP(emmc_nand_d4, 1), + GROUP(emmc_nand_d5, 1), + GROUP(emmc_nand_d6, 1), + GROUP(emmc_nand_d7, 1), + GROUP(emmc_clk, 1), + GROUP(emmc_cmd, 1), + GROUP(emmc_ds, 1), + GROUP(nand_ce0, 2), + GROUP(nand_ale, 2), + GROUP(nand_cle, 2), + GROUP(nand_wen_clk, 2), + GROUP(nand_ren_wr, 2), + GROUP(nand_rb0, 2), + GROUP(nor_hold, 3), + GROUP(nor_d, 3), + GROUP(nor_q, 3), + GROUP(nor_c, 3), + GROUP(nor_wp, 3), + GROUP(nor_cs, 3), + + /* bank GPIOZ */ + GROUP(spi_clk_a, 1), + GROUP(spi_mosi_a, 1), + GROUP(spi_miso_a, 1), + GROUP(spi_ss0_a, 1), + GROUP(spi_ss1_a, 1), + GROUP(spi_ss2_a, 1), + GROUP(i2c0_sck, 1), + GROUP(i2c0_sda, 1), + GROUP(i2c1_sck_z, 1), + GROUP(i2c1_sda_z, 1), + GROUP(uart_rts_b_z, 2), + GROUP(uart_cts_b_z, 2), + GROUP(uart_tx_b_z, 2), + GROUP(uart_rx_b_z, 2), + GROUP(pwm_a_z, 2), + GROUP(pwm_b_z, 2), + GROUP(spdif_in_z, 3), + GROUP(spdif_out_z, 3), + GROUP(uart_ao_tx_b_z, 2), + GROUP(uart_ao_rx_b_z, 2), + GROUP(uart_ao_cts_b_z, 2), + GROUP(uart_ao_rts_b_z, 2), + + /* bank GPIOX */ + GROUP(sdio_d0, 1), + GROUP(sdio_d1, 1), + GROUP(sdio_d2, 1), + GROUP(sdio_d3, 1), + GROUP(sdio_clk, 1), + GROUP(sdio_cmd, 1), + GROUP(i2c1_sck_x, 1), + GROUP(i2c1_sda_x, 1), + GROUP(i2c2_sck_x, 1), + GROUP(i2c2_sda_x, 1), + GROUP(uart_rts_a, 1), + GROUP(uart_cts_a, 1), + GROUP(uart_tx_a, 1), + GROUP(uart_rx_a, 1), + GROUP(uart_rts_b_x, 2), + GROUP(uart_cts_b_x, 2), + GROUP(uart_tx_b_x, 2), + GROUP(uart_rx_b_x, 2), + GROUP(jtag_tdo_x, 2), + GROUP(jtag_tdi_x, 2), + GROUP(jtag_clk_x, 2), + GROUP(jtag_tms_x, 2), + GROUP(spi_clk_b_x, 4), + GROUP(spi_mosi_b_x, 4), + GROUP(spi_miso_b_x, 4), + GROUP(spi_ss0_b_x, 4), + GROUP(pwm_a_x18, 3), + GROUP(pwm_a_x20, 1), + GROUP(pwm_b_x, 3), + GROUP(pwm_c_x10, 3), + GROUP(pwm_c_x17, 3), + GROUP(pwm_d_x11, 3), + GROUP(pwm_d_x16, 3), + GROUP(eth_txd0_x, 4), + GROUP(eth_txd1_x, 4), + GROUP(eth_txen_x, 4), + GROUP(eth_rgmii_rx_clk_x, 4), + GROUP(eth_rxd0_x, 4), + GROUP(eth_rxd1_x, 4), + GROUP(eth_rx_dv_x, 4), + GROUP(eth_mdio_x, 4), + GROUP(eth_mdc_x, 4), + + /* bank GPIOY */ + GROUP(eth_txd0_y, 1), + GROUP(eth_txd1_y, 1), + GROUP(eth_txen_y, 1), + GROUP(eth_rgmii_rx_clk_y, 1), + GROUP(eth_rxd0_y, 1), + GROUP(eth_rxd1_y, 1), + GROUP(eth_rx_dv_y, 1), + GROUP(eth_mdio_y, 1), + GROUP(eth_mdc_y, 1), + GROUP(eth_rxd2_rgmii, 1), + GROUP(eth_rxd3_rgmii, 1), + GROUP(eth_rgmii_tx_clk, 1), + GROUP(eth_txd2_rgmii, 1), + GROUP(eth_txd3_rgmii, 1), + + /* bank GPIOA */ + GROUP(spdif_out_a1, 4), + GROUP(spdif_out_a11, 3), + GROUP(spdif_out_a19, 2), + GROUP(spdif_out_a20, 1), + GROUP(spdif_in_a1, 3), + GROUP(spdif_in_a7, 3), + GROUP(spdif_in_a19, 1), + GROUP(spdif_in_a20, 2), + GROUP(spi_clk_b_a, 3), + GROUP(spi_mosi_b_a, 3), + GROUP(spi_miso_b_a, 3), + GROUP(spi_ss0_b_a, 3), + GROUP(spi_ss1_b, 3), + GROUP(pwm_a_a, 3), + GROUP(pwm_b_a, 3), + GROUP(pwm_c_a, 3), + GROUP(pwm_vs, 2), + GROUP(i2c2_sda_a, 3), + GROUP(i2c2_sck_a, 3), + GROUP(i2c3_sda_a6, 4), + GROUP(i2c3_sck_a7, 4), + GROUP(i2c3_sda_a12, 4), + GROUP(i2c3_sck_a13, 4), + GROUP(i2c3_sda_a19, 4), + GROUP(i2c3_sck_a20, 4), + GROUP(pdm_dclk_a14, 1), + GROUP(pdm_dclk_a19, 3), + GROUP(pdm_din0, 1), + GROUP(pdm_din1, 1), + GROUP(pdm_din2, 1), + GROUP(pdm_din3, 1), +}; + +/* uart_ao_a */ +static const unsigned int uart_ao_tx_a_pins[] = {GPIOAO_0}; +static const unsigned int uart_ao_rx_a_pins[] = {GPIOAO_1}; +static const unsigned int uart_ao_cts_a_pins[] = {GPIOAO_2}; +static const unsigned int uart_ao_rts_a_pins[] = {GPIOAO_3}; + +/* uart_ao_b */ +static const unsigned int uart_ao_tx_b_pins[] = {GPIOAO_4}; +static const unsigned int uart_ao_rx_b_pins[] = {GPIOAO_5}; +static const unsigned int uart_ao_cts_b_pins[] = {GPIOAO_2}; +static const unsigned int uart_ao_rts_b_pins[] = {GPIOAO_3}; + +/* i2c_ao */ +static const unsigned int i2c_ao_sck_4_pins[] = {GPIOAO_4}; +static const unsigned int i2c_ao_sda_5_pins[] = {GPIOAO_5}; +static const unsigned int i2c_ao_sck_8_pins[] = {GPIOAO_8}; +static const unsigned int i2c_ao_sda_9_pins[] = {GPIOAO_9}; +static const unsigned int i2c_ao_sck_10_pins[] = {GPIOAO_10}; +static const unsigned int i2c_ao_sda_11_pins[] = {GPIOAO_11}; + +/* i2c_ao_slave */ +static const unsigned int i2c_ao_slave_sck_pins[] = {GPIOAO_10}; +static const unsigned int i2c_ao_slave_sda_pins[] = {GPIOAO_11}; + +/* ir_in */ +static const unsigned int remote_input_ao_pins[] = {GPIOAO_6}; + +/* ir_out */ +static const unsigned int remote_out_ao_pins[] = {GPIOAO_7}; + +/* pwm_ao_a */ +static const unsigned int pwm_ao_a_pins[] = {GPIOAO_3}; + +/* pwm_ao_b */ +static const unsigned int pwm_ao_b_ao2_pins[] = {GPIOAO_2}; +static const unsigned int pwm_ao_b_ao12_pins[] = {GPIOAO_12}; + +/* pwm_ao_c */ +static const unsigned int pwm_ao_c_ao8_pins[] = {GPIOAO_8}; +static const unsigned int pwm_ao_c_ao13_pins[] = {GPIOAO_13}; + +/* pwm_ao_d */ +static const unsigned int pwm_ao_d_pins[] = {GPIOAO_9}; + +/* jtag_ao */ +static const unsigned int jtag_ao_tdi_pins[] = {GPIOAO_3}; +static const unsigned int jtag_ao_tdo_pins[] = {GPIOAO_4}; +static const unsigned int jtag_ao_clk_pins[] = {GPIOAO_5}; +static const unsigned int jtag_ao_tms_pins[] = {GPIOAO_7}; + +static struct meson_pmx_group meson_axg_aobus_groups[] = { + GPIO_GROUP(GPIOAO_0), + GPIO_GROUP(GPIOAO_1), + GPIO_GROUP(GPIOAO_2), + GPIO_GROUP(GPIOAO_3), + GPIO_GROUP(GPIOAO_4), + GPIO_GROUP(GPIOAO_5), + GPIO_GROUP(GPIOAO_6), + GPIO_GROUP(GPIOAO_7), + GPIO_GROUP(GPIOAO_8), + GPIO_GROUP(GPIOAO_9), + GPIO_GROUP(GPIOAO_10), + GPIO_GROUP(GPIOAO_11), + GPIO_GROUP(GPIOAO_12), + GPIO_GROUP(GPIOAO_13), + GPIO_GROUP(GPIO_TEST_N), + + /* bank AO */ + GROUP(uart_ao_tx_a, 1), + GROUP(uart_ao_rx_a, 1), + GROUP(uart_ao_cts_a, 2), + GROUP(uart_ao_rts_a, 2), + GROUP(uart_ao_tx_b, 1), + GROUP(uart_ao_rx_b, 1), + GROUP(uart_ao_cts_b, 1), + GROUP(uart_ao_rts_b, 1), + GROUP(i2c_ao_sck_4, 2), + GROUP(i2c_ao_sda_5, 2), + GROUP(i2c_ao_sck_8, 2), + GROUP(i2c_ao_sda_9, 2), + GROUP(i2c_ao_sck_10, 2), + GROUP(i2c_ao_sda_11, 2), + GROUP(i2c_ao_slave_sck, 1), + GROUP(i2c_ao_slave_sda, 1), + GROUP(remote_input_ao, 1), + GROUP(remote_out_ao, 1), + GROUP(pwm_ao_a, 3), + GROUP(pwm_ao_b_ao2, 3), + GROUP(pwm_ao_b_ao12, 3), + GROUP(pwm_ao_c_ao8, 3), + GROUP(pwm_ao_c_ao13, 3), + GROUP(pwm_ao_d, 3), + GROUP(jtag_ao_tdi, 4), + GROUP(jtag_ao_tdo, 4), + GROUP(jtag_ao_clk, 4), + GROUP(jtag_ao_tms, 4), +}; + +static const char * const gpio_periphs_groups[] = { + "GPIOZ_0", "GPIOZ_1", "GPIOZ_2", "GPIOZ_3", "GPIOZ_4", + "GPIOZ_5", "GPIOZ_6", "GPIOZ_7", "GPIOZ_8", "GPIOZ_9", + "GPIOZ_10", + + "BOOT_0", "BOOT_1", "BOOT_2", "BOOT_3", "BOOT_4", + "BOOT_5", "BOOT_6", "BOOT_7", "BOOT_8", "BOOT_9", + "BOOT_10", "BOOT_11", "BOOT_12", "BOOT_13", "BOOT_14", + + "GPIOA_0", "GPIOA_1", "GPIOA_2", "GPIOA_3", "GPIOA_4", + "GPIOA_5", "GPIOA_6", "GPIOA_7", "GPIOA_8", "GPIOA_9", + "GPIOA_10", "GPIOA_11", "GPIOA_12", "GPIOA_13", "GPIOA_14", + "GPIOA_15", "GPIOA_16", "GPIOA_17", "GPIOA_18", "GPIOA_19", + "GPIOA_20", + + "GPIOX_0", "GPIOX_1", "GPIOX_2", "GPIOX_3", "GPIOX_4", + "GPIOX_5", "GPIOX_6", "GPIOX_7", "GPIOX_8", "GPIOX_9", + "GPIOX_10", "GPIOX_11", "GPIOX_12", "GPIOX_13", "GPIOX_14", + "GPIOX_15", "GPIOX_16", "GPIOX_17", "GPIOX_18", "GPIOX_19", + "GPIOX_20", "GPIOX_21", "GPIOX_22", + + "GPIOY_0", "GPIOY_1", "GPIOY_2", "GPIOY_3", "GPIOY_4", + "GPIOY_5", "GPIOY_6", "GPIOY_7", "GPIOY_8", "GPIOY_9", + "GPIOY_10", "GPIOY_11", "GPIOY_12", "GPIOY_13", "GPIOY_14", + "GPIOY_15", +}; + +static const char * const emmc_groups[] = { + "emmc_nand_d0", "emmc_nand_d1", "emmc_nand_d2", + "emmc_nand_d3", "emmc_nand_d4", "emmc_nand_d5", + "emmc_nand_d6", "emmc_nand_d7", + "emmc_clk", "emmc_cmd", "emmc_ds", +}; + +static const char * const nand_groups[] = { + "emmc_nand_d0", "emmc_nand_d1", "emmc_nand_d2", + "emmc_nand_d3", "emmc_nand_d4", "emmc_nand_d5", + "emmc_nand_d6", "emmc_nand_d7", + "nand_ce0", "nand_ale", "nand_cle", + "nand_wen_clk", "nand_ren_wr", "nand_rb0", +}; + +static const char * const nor_groups[] = { + "nor_d", "nor_q", "nor_c", "nor_cs", + "nor_hold", "nor_wp", +}; + +static const char * const sdio_groups[] = { + "sdio_d0", "sdio_d1", "sdio_d2", "sdio_d3", + "sdio_cmd", "sdio_clk", +}; + +static const char * const spi_a_groups[] = { + "spi_clk_a", "spi_mosi_a", "spi_miso_a", "spi_ss0_a", + "spi_ss1_a", "spi_ss2_a" +}; + +static const char * const spi_b_groups[] = { + "spi_clk_b_x", "spi_mosi_b_x", "spi_miso_b_x", "spi_ss0_b_x", + "spi_clk_b_a", "spi_mosi_b_a", "spi_miso_b_a", "spi_ss0_b_a", + "spi_ss1_b" +}; + +static const char * const uart_a_groups[] = { + "uart_tx_a", "uart_rx_a", "uart_cts_a", "uart_rts_a", +}; + +static const char * const uart_b_groups[] = { + "uart_tx_b_z", "uart_rx_b_z", "uart_cts_b_z", "uart_rts_b_z", + "uart_tx_b_x", "uart_rx_b_x", "uart_cts_b_x", "uart_rts_b_x", +}; + +static const char * const uart_ao_b_gpioz_groups[] = { + "uart_ao_tx_b_z", "uart_ao_rx_b_z", + "uart_ao_cts_b_z", "uart_ao_rts_b_z", +}; + +static const char * const i2c0_groups[] = { + "i2c0_sck", "i2c0_sda", +}; + +static const char * const i2c1_groups[] = { + "i2c1_sck_z", "i2c1_sda_z", + "i2c1_sck_x", "i2c1_sda_x", +}; + +static const char * const i2c2_groups[] = { + "i2c2_sck_x", "i2c2_sda_x", + "i2c2_sda_a", "i2c2_sck_a", +}; + +static const char * const i2c3_groups[] = { + "i2c3_sda_a6", "i2c3_sck_a7", + "i2c3_sda_a12", "i2c3_sck_a13", + "i2c3_sda_a19", "i2c3_sck_a20", +}; + +static const char * const eth_groups[] = { + "eth_rxd2_rgmii", "eth_rxd3_rgmii", "eth_rgmii_tx_clk", + "eth_txd2_rgmii", "eth_txd3_rgmii", + "eth_txd0_x", "eth_txd1_x", "eth_txen_x", "eth_rgmii_rx_clk_x", + "eth_rxd0_x", "eth_rxd1_x", "eth_rx_dv_x", "eth_mdio_x", + "eth_mdc_x", + "eth_txd0_y", "eth_txd1_y", "eth_txen_y", "eth_rgmii_rx_clk_y", + "eth_rxd0_y", "eth_rxd1_y", "eth_rx_dv_y", "eth_mdio_y", + "eth_mdc_y", +}; + +static const char * const pwm_a_groups[] = { + "pwm_a_z", "pwm_a_x18", "pwm_a_x20", "pwm_a_a", +}; + +static const char * const pwm_b_groups[] = { + "pwm_b_z", "pwm_b_x", "pwm_b_a", +}; + +static const char * const pwm_c_groups[] = { + "pwm_c_x10", "pwm_c_x17", "pwm_c_a", +}; + +static const char * const pwm_d_groups[] = { + "pwm_d_x11", "pwm_d_x16", +}; + +static const char * const pwm_vs_groups[] = { + "pwm_vs", +}; + +static const char * const spdif_out_groups[] = { + "spdif_out_z", "spdif_out_a1", "spdif_out_a11", + "spdif_out_a19", "spdif_out_a20", +}; + +static const char * const spdif_in_groups[] = { + "spdif_in_z", "spdif_in_a1", "spdif_in_a7", + "spdif_in_a19", "spdif_in_a20", +}; + +static const char * const jtag_ee_groups[] = { + "jtag_tdo_x", "jtag_tdi_x", "jtag_clk_x", + "jtag_tms_x", +}; + +static const char * const pdm_groups[] = { + "pdm_din0", "pdm_din1", "pdm_din2", "pdm_din3", + "pdm_dclk_a14", "pdm_dclk_a19", +}; + +static const char * const gpio_aobus_groups[] = { + "GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4", + "GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9", + "GPIOAO_10", "GPIOAO_11", "GPIOAO_12", "GPIOAO_13", + "GPIO_TEST_N", +}; + +static const char * const uart_ao_a_groups[] = { + "uart_ao_tx_a", "uart_ao_rx_a", "uart_ao_cts_a", "uart_ao_rts_a", +}; + +static const char * const uart_ao_b_groups[] = { + "uart_ao_tx_b", "uart_ao_rx_b", "uart_ao_cts_b", "uart_ao_rts_b", +}; + +static const char * const i2c_ao_groups[] = { + "i2c_ao_sck_4", "i2c_ao_sda_5", + "i2c_ao_sck_8", "i2c_ao_sda_9", + "i2c_ao_sck_10", "i2c_ao_sda_11", +}; + +static const char * const i2c_ao_slave_groups[] = { + "i2c_ao_slave_sck", "i2c_ao_slave_sda", +}; + +static const char * const remote_input_ao_groups[] = { + "remote_input_ao", +}; + +static const char * const remote_out_ao_groups[] = { + "remote_out_ao", +}; + +static const char * const pwm_ao_a_groups[] = { + "pwm_ao_a", +}; + +static const char * const pwm_ao_b_groups[] = { + "pwm_ao_b_ao2", "pwm_ao_b_ao12", +}; + +static const char * const pwm_ao_c_groups[] = { + "pwm_ao_c_ao8", "pwm_ao_c_ao13", +}; + +static const char * const pwm_ao_d_groups[] = { + "pwm_ao_d", +}; + +static const char * const jtag_ao_groups[] = { + "jtag_ao_tdi", "jtag_ao_tdo", "jtag_ao_clk", "jtag_ao_tms", +}; + +static struct meson_pmx_func meson_axg_periphs_functions[] = { + FUNCTION(gpio_periphs), + FUNCTION(emmc), + FUNCTION(nor), + FUNCTION(spi_a), + FUNCTION(spi_b), + FUNCTION(sdio), + FUNCTION(nand), + FUNCTION(uart_a), + FUNCTION(uart_b), + FUNCTION(uart_ao_b_gpioz), + FUNCTION(i2c0), + FUNCTION(i2c1), + FUNCTION(i2c2), + FUNCTION(i2c3), + FUNCTION(eth), + FUNCTION(pwm_a), + FUNCTION(pwm_b), + FUNCTION(pwm_c), + FUNCTION(pwm_d), + FUNCTION(pwm_vs), + FUNCTION(spdif_out), + FUNCTION(spdif_in), + FUNCTION(jtag_ee), + FUNCTION(pdm), +}; + +static struct meson_pmx_func meson_axg_aobus_functions[] = { + FUNCTION(gpio_aobus), + FUNCTION(uart_ao_a), + FUNCTION(uart_ao_b), + FUNCTION(i2c_ao), + FUNCTION(i2c_ao_slave), + FUNCTION(remote_input_ao), + FUNCTION(remote_out_ao), + FUNCTION(pwm_ao_a), + FUNCTION(pwm_ao_b), + FUNCTION(pwm_ao_c), + FUNCTION(pwm_ao_d), + FUNCTION(jtag_ao), +}; + +static struct meson_bank meson_axg_periphs_banks[] = { + /* name first last irq pullen pull dir out in */ + BANK("Z", GPIOZ_0, GPIOZ_10, 14, 24, 3, 0, 3, 0, 9, 0, 10, 0, 11, 0), + BANK("BOOT", BOOT_0, BOOT_14, 25, 39, 4, 0, 4, 0, 12, 0, 13, 0, 14, 0), + BANK("A", GPIOA_0, GPIOA_20, 40, 60, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0), + BANK("X", GPIOX_0, GPIOX_22, 61, 83, 2, 0, 2, 0, 6, 0, 7, 0, 8, 0), + BANK("Y", GPIOY_0, GPIOY_15, 84, 99, 1, 0, 1, 0, 3, 0, 4, 0, 5, 0), +}; + +static struct meson_bank meson_axg_aobus_banks[] = { + /* name first last irq pullen pull dir out in */ + BANK("AO", GPIOAO_0, GPIOAO_9, 0, 13, 0, 16, 0, 0, 0, 0, 0, 16, 1, 0), +}; + +static struct meson_pmx_bank meson_axg_periphs_pmx_banks[] = { + /* name first lask reg offset */ + BANK_PMX("Z", GPIOZ_0, GPIOZ_10, 0x2, 0), + BANK_PMX("BOOT", BOOT_0, BOOT_14, 0x0, 0), + BANK_PMX("A", GPIOA_0, GPIOA_20, 0xb, 0), + BANK_PMX("X", GPIOX_0, GPIOX_22, 0x4, 0), + BANK_PMX("Y", GPIOY_0, GPIOY_15, 0x8, 0), +}; + +static struct meson_axg_pmx_data meson_axg_periphs_pmx_banks_data = { + .pmx_banks = meson_axg_periphs_pmx_banks, + .num_pmx_banks = ARRAY_SIZE(meson_axg_periphs_pmx_banks), +}; + +static struct meson_pmx_bank meson_axg_aobus_pmx_banks[] = { + BANK_PMX("AO", GPIOAO_0, GPIOAO_13, 0x0, 0), +}; + +static struct meson_axg_pmx_data meson_axg_aobus_pmx_banks_data = { + .pmx_banks = meson_axg_aobus_pmx_banks, + .num_pmx_banks = ARRAY_SIZE(meson_axg_aobus_pmx_banks), +}; + +static struct meson_pinctrl_data meson_axg_periphs_pinctrl_data = { + .name = "periphs-banks", + .pins = meson_axg_periphs_pins, + .groups = meson_axg_periphs_groups, + .funcs = meson_axg_periphs_functions, + .banks = meson_axg_periphs_banks, + .num_pins = ARRAY_SIZE(meson_axg_periphs_pins), + .num_groups = ARRAY_SIZE(meson_axg_periphs_groups), + .num_funcs = ARRAY_SIZE(meson_axg_periphs_functions), + .num_banks = ARRAY_SIZE(meson_axg_periphs_banks), + .pmx_ops = &meson_axg_pmx_ops, + .pmx_data = &meson_axg_periphs_pmx_banks_data, +}; + +static struct meson_pinctrl_data meson_axg_aobus_pinctrl_data = { + .name = "aobus-banks", + .pins = meson_axg_aobus_pins, + .groups = meson_axg_aobus_groups, + .funcs = meson_axg_aobus_functions, + .banks = meson_axg_aobus_banks, + .num_pins = ARRAY_SIZE(meson_axg_aobus_pins), + .num_groups = ARRAY_SIZE(meson_axg_aobus_groups), + .num_funcs = ARRAY_SIZE(meson_axg_aobus_functions), + .num_banks = ARRAY_SIZE(meson_axg_aobus_banks), + .pmx_ops = &meson_axg_pmx_ops, + .pmx_data = &meson_axg_aobus_pmx_banks_data, +}; + +static const struct of_device_id meson_axg_pinctrl_dt_match[] = { + { + .compatible = "amlogic,meson-axg-periphs-pinctrl", + .data = &meson_axg_periphs_pinctrl_data, + }, + { + .compatible = "amlogic,meson-axg-aobus-pinctrl", + .data = &meson_axg_aobus_pinctrl_data, + }, + { }, +}; + +static struct platform_driver meson_axg_pinctrl_driver = { + .probe = meson_pinctrl_probe, + .driver = { + .name = "meson-axg-pinctrl", + .of_match_table = meson_axg_pinctrl_dt_match, + }, +}; + +builtin_platform_driver(meson_axg_pinctrl_driver); diff --git a/drivers/pinctrl/meson/pinctrl-meson.h b/drivers/pinctrl/meson/pinctrl-meson.h index 183b6e471635..12a391109329 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.h +++ b/drivers/pinctrl/meson/pinctrl-meson.h @@ -108,6 +108,7 @@ struct meson_pinctrl_data { struct meson_bank *banks; unsigned int num_banks; const struct pinmux_ops *pmx_ops; + void *pmx_data; }; struct meson_pinctrl { diff --git a/drivers/pinctrl/pinctrl-gemini.c b/drivers/pinctrl/pinctrl-gemini.c index e9b83e291edf..5e789753f945 100644 --- a/drivers/pinctrl/pinctrl-gemini.c +++ b/drivers/pinctrl/pinctrl-gemini.c @@ -67,6 +67,9 @@ struct gemini_pmx { * elements in .pins so we can iterate over that array * @mask: bits to clear to enable this when doing pin muxing * @value: bits to set to enable this when doing pin muxing + * @driving_mask: bitmask for the IO Pad driving register for this + * group, if it supports altering the driving strength of + * its lines. */ struct gemini_pin_group { const char *name; @@ -74,12 +77,14 @@ struct gemini_pin_group { const unsigned int num_pins; u32 mask; u32 value; + u32 driving_mask; }; /* Some straight-forward control registers */ #define GLOBAL_WORD_ID 0x00 #define GLOBAL_STATUS 0x04 #define GLOBAL_STATUS_FLPIN BIT(20) +#define GLOBAL_IODRIVE 0x10 #define GLOBAL_GMAC_CTRL_SKEW 0x1c #define GLOBAL_GMAC0_DATA_SKEW 0x20 #define GLOBAL_GMAC1_DATA_SKEW 0x24 @@ -738,6 +743,7 @@ static const struct gemini_pin_group gemini_3512_pin_groups[] = { /* Conflict with all flash usage */ .value = IDE_PADS_ENABLE | NAND_PADS_DISABLE | PFLASH_PADS_DISABLE | SFLASH_PADS_DISABLE, + .driving_mask = GENMASK(21, 20), }, { .name = "satagrp", @@ -753,6 +759,7 @@ static const struct gemini_pin_group gemini_3512_pin_groups[] = { .name = "gmii_gmac0_grp", .pins = gmii_gmac0_3512_pins, .num_pins = ARRAY_SIZE(gmii_gmac0_3512_pins), + .driving_mask = GENMASK(17, 16), }, { .name = "gmii_gmac1_grp", @@ -760,6 +767,7 @@ static const struct gemini_pin_group gemini_3512_pin_groups[] = { .num_pins = ARRAY_SIZE(gmii_gmac1_3512_pins), /* Bring out RGMII on the GMAC1 pins */ .value = GEMINI_GMAC_IOSEL_GMAC0_GMAC1_RGMII, + .driving_mask = GENMASK(19, 18), }, { .name = "pcigrp", @@ -767,6 +775,7 @@ static const struct gemini_pin_group gemini_3512_pin_groups[] = { .num_pins = ARRAY_SIZE(pci_3512_pins), /* Conflict only with GPIO2 */ .value = PCI_PADS_ENABLE | PCI_CLK_PAD_ENABLE, + .driving_mask = GENMASK(23, 22), }, { .name = "lpcgrp", @@ -1671,6 +1680,7 @@ static const struct gemini_pin_group gemini_3516_pin_groups[] = { /* Conflict with all flash usage */ .value = IDE_PADS_ENABLE | NAND_PADS_DISABLE | PFLASH_PADS_DISABLE | SFLASH_PADS_DISABLE, + .driving_mask = GENMASK(21, 20), }, { .name = "satagrp", @@ -1686,6 +1696,7 @@ static const struct gemini_pin_group gemini_3516_pin_groups[] = { .name = "gmii_gmac0_grp", .pins = gmii_gmac0_3516_pins, .num_pins = ARRAY_SIZE(gmii_gmac0_3516_pins), + .driving_mask = GENMASK(17, 16), }, { .name = "gmii_gmac1_grp", @@ -1693,6 +1704,7 @@ static const struct gemini_pin_group gemini_3516_pin_groups[] = { .num_pins = ARRAY_SIZE(gmii_gmac1_3516_pins), /* Bring out RGMII on the GMAC1 pins */ .value = GEMINI_GMAC_IOSEL_GMAC0_GMAC1_RGMII, + .driving_mask = GENMASK(19, 18), }, { .name = "pcigrp", @@ -1700,6 +1712,7 @@ static const struct gemini_pin_group gemini_3516_pin_groups[] = { .num_pins = ARRAY_SIZE(pci_3516_pins), /* Conflict only with GPIO2 */ .value = PCI_PADS_ENABLE | PCI_CLK_PAD_ENABLE, + .driving_mask = GENMASK(23, 22), }, { .name = "lpcgrp", @@ -2015,7 +2028,8 @@ static const char * const sflashgrps[] = { "sflashgrp" }; static const char * const gpio0grps[] = { "gpio0agrp", "gpio0bgrp", "gpio0cgrp", "gpio0dgrp", "gpio0egrp", "gpio0fgrp", "gpio0ggrp", "gpio0hgrp", "gpio0igrp", - "gpio0jgrp", "gpio0kgrp" }; + "gpio0jgrp", "gpio0kgrp", "gpio0lgrp", + "gpio0mgrp" }; static const char * const gpio1grps[] = { "gpio1agrp", "gpio1bgrp", "gpio1cgrp", "gpio1dgrp" }; static const char * const gpio2grps[] = { "gpio2agrp", "gpio2bgrp", "gpio2cgrp" }; @@ -2393,9 +2407,77 @@ static int gemini_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, return ret; } +static int gemini_pinconf_group_set(struct pinctrl_dev *pctldev, + unsigned selector, + unsigned long *configs, + unsigned num_configs) +{ + struct gemini_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); + const struct gemini_pin_group *grp = NULL; + enum pin_config_param param; + u32 arg; + u32 val; + int i; + + if (pmx->is_3512) + grp = &gemini_3512_pin_groups[selector]; + if (pmx->is_3516) + grp = &gemini_3516_pin_groups[selector]; + + /* First figure out if this group supports configs */ + if (!grp->driving_mask) { + dev_err(pmx->dev, "pin config group \"%s\" does " + "not support drive strength setting\n", + grp->name); + return -EINVAL; + } + + for (i = 0; i < num_configs; i++) { + param = pinconf_to_config_param(configs[i]); + arg = pinconf_to_config_argument(configs[i]); + + switch (param) { + case PIN_CONFIG_DRIVE_STRENGTH: + switch (arg) { + case 4: + val = 0; + break; + case 8: + val = 1; + break; + case 12: + val = 2; + break; + case 16: + val = 3; + break; + default: + dev_err(pmx->dev, + "invalid drive strength %d mA\n", + arg); + return -ENOTSUPP; + } + val <<= (ffs(grp->driving_mask) - 1); + regmap_update_bits(pmx->map, GLOBAL_IODRIVE, + grp->driving_mask, + val); + dev_info(pmx->dev, + "set group %s to %d mA drive strength mask %08x val %08x\n", + grp->name, arg, grp->driving_mask, val); + break; + default: + dev_err(pmx->dev, "invalid config param %04x\n", param); + return -ENOTSUPP; + } + } + + return 0; +} + static const struct pinconf_ops gemini_pinconf_ops = { .pin_config_get = gemini_pinconf_get, .pin_config_set = gemini_pinconf_set, + .pin_config_group_set = gemini_pinconf_group_set, .is_generic = true, }; diff --git a/drivers/pinctrl/pinctrl-mcp23s08.c b/drivers/pinctrl/pinctrl-mcp23s08.c index 4a6ea159c65d..e6ad36dea3e5 100644 --- a/drivers/pinctrl/pinctrl-mcp23s08.c +++ b/drivers/pinctrl/pinctrl-mcp23s08.c @@ -455,31 +455,22 @@ static irqreturn_t mcp23s08_irq(int irq, void *data) defval_changed, gpio_set; mutex_lock(&mcp->lock); - if (mcp_read(mcp, MCP_INTF, &intf) < 0) { - mutex_unlock(&mcp->lock); - return IRQ_HANDLED; - } + if (mcp_read(mcp, MCP_INTF, &intf)) + goto unlock; - if (mcp_read(mcp, MCP_INTCAP, &intcap) < 0) { - mutex_unlock(&mcp->lock); - return IRQ_HANDLED; - } + if (mcp_read(mcp, MCP_INTCAP, &intcap)) + goto unlock; - if (mcp_read(mcp, MCP_INTCON, &intcon) < 0) { - mutex_unlock(&mcp->lock); - return IRQ_HANDLED; - } + if (mcp_read(mcp, MCP_INTCON, &intcon)) + goto unlock; - if (mcp_read(mcp, MCP_DEFVAL, &defval) < 0) { - mutex_unlock(&mcp->lock); - return IRQ_HANDLED; - } + if (mcp_read(mcp, MCP_DEFVAL, &defval)) + goto unlock; /* This clears the interrupt(configurable on S18) */ - if (mcp_read(mcp, MCP_GPIO, &gpio) < 0) { - mutex_unlock(&mcp->lock); - return IRQ_HANDLED; - } + if (mcp_read(mcp, MCP_GPIO, &gpio)) + goto unlock; + gpio_orig = mcp->cached_gpio; mcp->cached_gpio = gpio; mutex_unlock(&mcp->lock); @@ -541,6 +532,10 @@ static irqreturn_t mcp23s08_irq(int irq, void *data) } return IRQ_HANDLED; + +unlock: + mutex_unlock(&mcp->lock); + return IRQ_HANDLED; } static void mcp23s08_irq_mask(struct irq_data *data) diff --git a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c index 866aa3ce1ac9..6cf0006d4c8d 100644 --- a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c +++ b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c @@ -436,3 +436,7 @@ int pxa2xx_pinctrl_exit(struct platform_device *pdev) return 0; } EXPORT_SYMBOL_GPL(pxa2xx_pinctrl_exit); + +MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>"); +MODULE_DESCRIPTION("Marvell PXA2xx pinctrl driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index a276c61be217..82bb617e8c61 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -1,7 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) Maxime Coquelin 2015 + * Copyright (C) STMicroelectronics 2017 * Author: Maxime Coquelin <mcoquelin.stm32@gmail.com> - * License terms: GNU General Public License (GPL), version 2 * * Heavily based on Mediatek's pinctrl driver */ diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.h b/drivers/pinctrl/stm32/pinctrl-stm32.h index 8702a9992ce5..473a6238a27b 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.h +++ b/drivers/pinctrl/stm32/pinctrl-stm32.h @@ -1,7 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) Maxime Coquelin 2015 + * Copyright (C) STMicroelectronics 2017 * Author: Maxime Coquelin <mcoquelin.stm32@gmail.com> - * License terms: GNU General Public License (GPL), version 2 */ #ifndef __PINCTRL_STM32_H #define __PINCTRL_STM32_H diff --git a/drivers/pinctrl/stm32/pinctrl-stm32f429.c b/drivers/pinctrl/stm32/pinctrl-stm32f429.c index 4bbade25acc6..663a97113c51 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32f429.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32f429.c @@ -1,7 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) Maxime Coquelin 2015 + * Copyright (C) STMicroelectronics 2017 * Author: Maxime Coquelin <mcoquelin.stm32@gmail.com> - * License terms: GNU General Public License (GPL), version 2 */ #include <linux/init.h> #include <linux/of.h> diff --git a/drivers/pinctrl/stm32/pinctrl-stm32f469.c b/drivers/pinctrl/stm32/pinctrl-stm32f469.c index 86c8cebfa9b9..ed5397f6d7f2 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32f469.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32f469.c @@ -1,7 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * Copyright (C) Alexandre Torgue 2016 - * Author: Alexandre Torgue <alexandre.torgue@st.com> - * License terms: GNU General Public License (GPL), version 2 + * Copyright (C) STMicroelectronics 2017 + * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics. */ #include <linux/init.h> #include <linux/of.h> diff --git a/drivers/pinctrl/stm32/pinctrl-stm32f746.c b/drivers/pinctrl/stm32/pinctrl-stm32f746.c index a2fae7357c36..d832aab7ebe1 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32f746.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32f746.c @@ -1,7 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) Maxime Coquelin 2015 + * Copyright (C) STMicroelectronics 2017 * Author: Maxime Coquelin <mcoquelin.stm32@gmail.com> - * License terms: GNU General Public License (GPL), version 2 */ #include <linux/init.h> #include <linux/of.h> diff --git a/drivers/pinctrl/stm32/pinctrl-stm32h743.c b/drivers/pinctrl/stm32/pinctrl-stm32h743.c index e34b2b9217ce..ffe7b5271506 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32h743.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32h743.c @@ -1,7 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * Copyright (C) Alexandre Torgue 2017 - * Author: Alexandre Torgue <alexandre.torgue@st.com> - * License terms: GNU General Public License (GPL), version 2 + * Copyright (C) STMicroelectronics 2017 + * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics. */ #include <linux/init.h> #include <linux/of.h> |