diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-13 16:59:10 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-13 16:59:10 +0100 |
commit | 20d5ba4928ceb79b919092c939ae4ef4d88807bd (patch) | |
tree | f8bd3653a63baa80a02be48443575ae83ac1d290 /drivers/pinctrl | |
parent | Merge tag 'gpio-v4.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/lin... (diff) | |
parent | pinctrl: sx150x: use new nested IRQ infrastructure (diff) | |
download | linux-20d5ba4928ceb79b919092c939ae4ef4d88807bd.tar.xz linux-20d5ba4928ceb79b919092c939ae4ef4d88807bd.zip |
Merge tag 'pinctrl-v4.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl
Pull pinctrl updates from Linus Walleij:
"Bulk pin control changes for the v4.10 kernel cycle:
No core changes this time. Mainly gradual improvement and
feature growth in the drivers.
New drivers:
- New driver for TI DA850/OMAP-L138/AM18XX pinconf
- The SX150x was moved over from the GPIO subsystem and reimagined as
a pin control driver with GPIO support in a joint effort by three
independent users of this hardware. The result was amazingly good!
- New subdriver for the Oxnas OX820
Improvements:
- The sunxi driver now supports the generic pin control bindings
rather than the sunxi-specific. Add debouncing support to the
driver.
- Simplifications in pinctrl-single adding a generic parser.
- Two downstream fixes and move the Raspberry Pi BCM2835 over to use
the generic GPIOLIB_IRQCHIP"
* tag 'pinctrl-v4.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (92 commits)
pinctrl: sx150x: use new nested IRQ infrastructure
pinctrl: sx150x: handle missing 'advanced' reg in sx1504 and sx1505
pinctrl: sx150x: rename 'reg_advance' to 'reg_advanced'
pinctrl: sx150x: access the correct bits in the 4-bit regs of sx150[147]
pinctrl: mt8173: set GPIO16 to usb iddig mode
pinctrl: bcm2835: switch to GPIOLIB_IRQCHIP
pinctrl: New driver for TI DA850/OMAP-L138/AM18XX pinconf
devicetree: bindings: pinctrl: Add binding for ti,da850-pupd
Documentation: pinctrl: palmas: Add ti,palmas-powerhold-override property definition
pinctrl: intel: set default handler to be handle_bad_irq()
pinctrl: sx150x: add support for sx1501, sx1504, sx1505 and sx1507
pinctrl: sx150x: sort chips by part number
pinctrl: sx150x: use correct registers for reg_sense (sx1502 and sx1508)
pinctrl: imx: fix imx_pinctrl_desc initialization
pinctrl: sx150x: support setting multiple pins at once
pinctrl: sx150x: various spelling fixes and some white-space cleanup
pinctrl: mediatek: use builtin_platform_driver
pinctrl: stm32: use builtin_platform_driver
pinctrl: sunxi: Testing the wrong variable
pinctrl: nomadik: split up and comments MC0 pins
...
Diffstat (limited to 'drivers/pinctrl')
66 files changed, 5688 insertions, 1345 deletions
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 801fa8bb05e1..54044a8ecbd7 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -93,6 +93,15 @@ config PINCTRL_AMD Requires ACPI/FDT device enumeration code to set up a platform device. +config PINCTRL_DA850_PUPD + tristate "TI DA850/OMAP-L138/AM18XX pullup/pulldown groups" + depends on OF && (ARCH_DAVINCI_DA850 || COMPILE_TEST) + select PINCONF + select GENERIC_PINCONF + help + Driver for TI DA850/OMAP-L138/AM18XX pinconf. Used to control + pullup/pulldown pin groups. + config PINCTRL_DIGICOLOR bool depends on OF && (ARCH_DIGICOLOR || COMPILE_TEST) @@ -171,6 +180,7 @@ config PINCTRL_SX150X select PINCONF select GENERIC_PINCONF select GPIOLIB_IRQCHIP + select REGMAP help Say yes here to provide support for Semtech SX150x-series I2C GPIO expanders as pinctrl module. @@ -223,7 +233,7 @@ config PINCTRL_COH901 config PINCTRL_MAX77620 tristate "MAX77620/MAX20024 Pincontrol support" - depends on MFD_MAX77620 + depends on MFD_MAX77620 && OF select PINMUX select GENERIC_PINCONF help diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 3b8e6f726acb..25d50a86981d 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_PINCTRL_BF60x) += pinctrl-adi2-bf60x.o obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o obj-$(CONFIG_PINCTRL_AMD) += pinctrl-amd.o +obj-$(CONFIG_PINCTRL_DA850_PUPD) += pinctrl-da850-pupd.o obj-$(CONFIG_PINCTRL_DIGICOLOR) += pinctrl-digicolor.o obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o obj-$(CONFIG_PINCTRL_MAX77620) += pinctrl-max77620.o diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig index 63246770bd74..8968dd7aebed 100644 --- a/drivers/pinctrl/bcm/Kconfig +++ b/drivers/pinctrl/bcm/Kconfig @@ -20,6 +20,7 @@ config PINCTRL_BCM2835 bool select PINMUX select PINCONF + select GPIOLIB_IRQCHIP config PINCTRL_IPROC_GPIO bool "Broadcom iProc GPIO (with PINCONF) driver" diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c index fa77165fab2c..1bb38d0493eb 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -24,11 +24,9 @@ #include <linux/device.h> #include <linux/err.h> #include <linux/gpio/driver.h> -#include <linux/interrupt.h> #include <linux/io.h> #include <linux/irq.h> #include <linux/irqdesc.h> -#include <linux/irqdomain.h> #include <linux/module.h> #include <linux/of_address.h> #include <linux/of.h> @@ -47,6 +45,7 @@ #define MODULE_NAME "pinctrl-bcm2835" #define BCM2835_NUM_GPIOS 54 #define BCM2835_NUM_BANKS 2 +#define BCM2835_NUM_IRQS 3 #define BCM2835_PIN_BITMAP_SZ \ DIV_ROUND_UP(BCM2835_NUM_GPIOS, sizeof(unsigned long) * 8) @@ -86,31 +85,23 @@ enum bcm2835_pinconf_pull { #define BCM2835_PINCONF_UNPACK_PARAM(_conf_) ((_conf_) >> 16) #define BCM2835_PINCONF_UNPACK_ARG(_conf_) ((_conf_) & 0xffff) -struct bcm2835_gpio_irqdata { - struct bcm2835_pinctrl *pc; - int bank; -}; - struct bcm2835_pinctrl { struct device *dev; void __iomem *base; - int irq[BCM2835_NUM_BANKS]; + int irq[BCM2835_NUM_IRQS]; /* note: locking assumes each bank will have its own unsigned long */ unsigned long enabled_irq_map[BCM2835_NUM_BANKS]; unsigned int irq_type[BCM2835_NUM_GPIOS]; struct pinctrl_dev *pctl_dev; - struct irq_domain *irq_domain; struct gpio_chip gpio_chip; struct pinctrl_gpio_range gpio_range; - struct bcm2835_gpio_irqdata irq_data[BCM2835_NUM_BANKS]; + int irq_group[BCM2835_NUM_IRQS]; spinlock_t irq_lock[BCM2835_NUM_BANKS]; }; -static struct lock_class_key gpio_lock_class; - /* pins are just named GPIO0..GPIO53 */ #define BCM2835_GPIO_PIN(a) PINCTRL_PIN(a, "gpio" #a) static struct pinctrl_pin_desc bcm2835_gpio_pins[] = { @@ -368,13 +359,6 @@ static int bcm2835_gpio_direction_output(struct gpio_chip *chip, return pinctrl_gpio_direction_output(chip->base + offset); } -static int bcm2835_gpio_to_irq(struct gpio_chip *chip, unsigned offset) -{ - struct bcm2835_pinctrl *pc = gpiochip_get_data(chip); - - return irq_linear_revmap(pc->irq_domain, offset); -} - static struct gpio_chip bcm2835_gpio_chip = { .label = MODULE_NAME, .owner = THIS_MODULE, @@ -385,31 +369,67 @@ static struct gpio_chip bcm2835_gpio_chip = { .get_direction = bcm2835_gpio_get_direction, .get = bcm2835_gpio_get, .set = bcm2835_gpio_set, - .to_irq = bcm2835_gpio_to_irq, .base = -1, .ngpio = BCM2835_NUM_GPIOS, .can_sleep = false, }; -static irqreturn_t bcm2835_gpio_irq_handler(int irq, void *dev_id) +static void bcm2835_gpio_irq_handle_bank(struct bcm2835_pinctrl *pc, + unsigned int bank, u32 mask) { - struct bcm2835_gpio_irqdata *irqdata = dev_id; - struct bcm2835_pinctrl *pc = irqdata->pc; - int bank = irqdata->bank; unsigned long events; unsigned offset; unsigned gpio; unsigned int type; events = bcm2835_gpio_rd(pc, GPEDS0 + bank * 4); + events &= mask; events &= pc->enabled_irq_map[bank]; for_each_set_bit(offset, &events, 32) { gpio = (32 * bank) + offset; + /* FIXME: no clue why the code looks up the type here */ type = pc->irq_type[gpio]; - generic_handle_irq(irq_linear_revmap(pc->irq_domain, gpio)); + generic_handle_irq(irq_linear_revmap(pc->gpio_chip.irqdomain, + gpio)); } - return events ? IRQ_HANDLED : IRQ_NONE; +} + +static void bcm2835_gpio_irq_handler(struct irq_desc *desc) +{ + struct gpio_chip *chip = irq_desc_get_handler_data(desc); + struct bcm2835_pinctrl *pc = gpiochip_get_data(chip); + struct irq_chip *host_chip = irq_desc_get_chip(desc); + int irq = irq_desc_get_irq(desc); + int group; + int i; + + for (i = 0; i < ARRAY_SIZE(pc->irq); i++) { + if (pc->irq[i] == irq) { + group = pc->irq_group[i]; + break; + } + } + /* This should not happen, every IRQ has a bank */ + if (i == ARRAY_SIZE(pc->irq)) + BUG(); + + chained_irq_enter(host_chip, desc); + + switch (group) { + case 0: /* IRQ0 covers GPIOs 0-27 */ + bcm2835_gpio_irq_handle_bank(pc, 0, 0x0fffffff); + break; + case 1: /* IRQ1 covers GPIOs 28-45 */ + bcm2835_gpio_irq_handle_bank(pc, 0, 0xf0000000); + bcm2835_gpio_irq_handle_bank(pc, 1, 0x00003fff); + break; + case 2: /* IRQ2 covers GPIOs 46-53 */ + bcm2835_gpio_irq_handle_bank(pc, 1, 0x003fc000); + break; + } + + chained_irq_exit(host_chip, desc); } static inline void __bcm2835_gpio_irq_config(struct bcm2835_pinctrl *pc, @@ -455,7 +475,8 @@ static void bcm2835_gpio_irq_config(struct bcm2835_pinctrl *pc, static void bcm2835_gpio_irq_enable(struct irq_data *data) { - struct bcm2835_pinctrl *pc = irq_data_get_irq_chip_data(data); + struct gpio_chip *chip = irq_data_get_irq_chip_data(data); + struct bcm2835_pinctrl *pc = gpiochip_get_data(chip); unsigned gpio = irqd_to_hwirq(data); unsigned offset = GPIO_REG_SHIFT(gpio); unsigned bank = GPIO_REG_OFFSET(gpio); @@ -469,7 +490,8 @@ static void bcm2835_gpio_irq_enable(struct irq_data *data) static void bcm2835_gpio_irq_disable(struct irq_data *data) { - struct bcm2835_pinctrl *pc = irq_data_get_irq_chip_data(data); + struct gpio_chip *chip = irq_data_get_irq_chip_data(data); + struct bcm2835_pinctrl *pc = gpiochip_get_data(chip); unsigned gpio = irqd_to_hwirq(data); unsigned offset = GPIO_REG_SHIFT(gpio); unsigned bank = GPIO_REG_OFFSET(gpio); @@ -575,7 +597,8 @@ static int __bcm2835_gpio_irq_set_type_enabled(struct bcm2835_pinctrl *pc, static int bcm2835_gpio_irq_set_type(struct irq_data *data, unsigned int type) { - struct bcm2835_pinctrl *pc = irq_data_get_irq_chip_data(data); + struct gpio_chip *chip = irq_data_get_irq_chip_data(data); + struct bcm2835_pinctrl *pc = gpiochip_get_data(chip); unsigned gpio = irqd_to_hwirq(data); unsigned offset = GPIO_REG_SHIFT(gpio); unsigned bank = GPIO_REG_OFFSET(gpio); @@ -601,7 +624,8 @@ static int bcm2835_gpio_irq_set_type(struct irq_data *data, unsigned int type) static void bcm2835_gpio_irq_ack(struct irq_data *data) { - struct bcm2835_pinctrl *pc = irq_data_get_irq_chip_data(data); + struct gpio_chip *chip = irq_data_get_irq_chip_data(data); + struct bcm2835_pinctrl *pc = gpiochip_get_data(chip); unsigned gpio = irqd_to_hwirq(data); bcm2835_gpio_set_bit(pc, GPEDS0, gpio); @@ -644,10 +668,11 @@ static void bcm2835_pctl_pin_dbg_show(struct pinctrl_dev *pctldev, unsigned offset) { struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + struct gpio_chip *chip = &pc->gpio_chip; enum bcm2835_fsel fsel = bcm2835_pinctrl_fsel_get(pc, offset); const char *fname = bcm2835_functions[fsel]; int value = bcm2835_gpio_get_bit(pc, GPLEV0, offset); - int irq = irq_find_mapping(pc->irq_domain, offset); + int irq = irq_find_mapping(chip->irqdomain, offset); seq_printf(s, "function %s in %s; irq %d (%s)", fname, value ? "hi" : "lo", @@ -821,6 +846,16 @@ static const struct pinctrl_ops bcm2835_pctl_ops = { .dt_free_map = bcm2835_pctl_dt_free_map, }; +static int bcm2835_pmx_free(struct pinctrl_dev *pctldev, + unsigned offset) +{ + struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); + + /* disable by setting to GPIO_IN */ + bcm2835_pinctrl_fsel_set(pc, offset, BCM2835_FSEL_GPIO_IN); + return 0; +} + static int bcm2835_pmx_get_functions_count(struct pinctrl_dev *pctldev) { return BCM2835_FSEL_COUNT; @@ -880,6 +915,7 @@ static int bcm2835_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, } static const struct pinmux_ops bcm2835_pmx_ops = { + .free = bcm2835_pmx_free, .get_functions_count = bcm2835_pmx_get_functions_count, .get_function_name = bcm2835_pmx_get_function_name, .get_function_groups = bcm2835_pmx_get_function_groups, @@ -917,12 +953,14 @@ static int bcm2835_pinconf_set(struct pinctrl_dev *pctldev, bcm2835_gpio_wr(pc, GPPUD, arg & 3); /* - * Docs say to wait 150 cycles, but not of what. We assume a - * 1 MHz clock here, which is pretty slow... + * BCM2835 datasheet say to wait 150 cycles, but not of what. + * But the VideoCore firmware delay for this operation + * based nearly on the same amount of VPU cycles and this clock + * runs at 250 MHz. */ - udelay(150); + udelay(1); bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), BIT(bit)); - udelay(150); + udelay(1); bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), 0); } /* for each config */ @@ -980,26 +1018,9 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) pc->gpio_chip.parent = dev; pc->gpio_chip.of_node = np; - pc->irq_domain = irq_domain_add_linear(np, BCM2835_NUM_GPIOS, - &irq_domain_simple_ops, NULL); - if (!pc->irq_domain) { - dev_err(dev, "could not create IRQ domain\n"); - return -ENOMEM; - } - - for (i = 0; i < BCM2835_NUM_GPIOS; i++) { - int irq = irq_create_mapping(pc->irq_domain, i); - irq_set_lockdep_class(irq, &gpio_lock_class); - irq_set_chip_and_handler(irq, &bcm2835_gpio_irq_chip, - handle_level_irq); - irq_set_chip_data(irq, pc); - } - for (i = 0; i < BCM2835_NUM_BANKS; i++) { unsigned long events; unsigned offset; - int len; - char *name; /* clear event detection flags */ bcm2835_gpio_wr(pc, GPREN0 + i * 4, 0); @@ -1014,24 +1035,7 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) for_each_set_bit(offset, &events, 32) bcm2835_gpio_wr(pc, GPEDS0 + i * 4, BIT(offset)); - pc->irq[i] = irq_of_parse_and_map(np, i); - pc->irq_data[i].pc = pc; - pc->irq_data[i].bank = i; spin_lock_init(&pc->irq_lock[i]); - - len = strlen(dev_name(pc->dev)) + 16; - name = devm_kzalloc(pc->dev, len, GFP_KERNEL); - if (!name) - return -ENOMEM; - snprintf(name, len, "%s:bank%d", dev_name(pc->dev), i); - - err = devm_request_irq(dev, pc->irq[i], - bcm2835_gpio_irq_handler, IRQF_SHARED, - name, &pc->irq_data[i]); - if (err) { - dev_err(dev, "unable to request IRQ %d\n", pc->irq[i]); - return err; - } } err = gpiochip_add_data(&pc->gpio_chip, pc); @@ -1040,6 +1044,29 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) return err; } + err = gpiochip_irqchip_add(&pc->gpio_chip, &bcm2835_gpio_irq_chip, + 0, handle_level_irq, IRQ_TYPE_NONE); + if (err) { + dev_info(dev, "could not add irqchip\n"); + return err; + } + + for (i = 0; i < BCM2835_NUM_IRQS; i++) { + pc->irq[i] = irq_of_parse_and_map(np, i); + pc->irq_group[i] = i; + /* + * Use the same handler for all groups: this is necessary + * since we use one gpiochip to cover all lines - the + * irq handler then needs to figure out which group and + * bank that was firing the IRQ and look up the per-group + * and bank data. + */ + gpiochip_set_chained_irqchip(&pc->gpio_chip, + &bcm2835_gpio_irq_chip, + pc->irq[i], + bcm2835_gpio_irq_handler); + } + pc->pctl_dev = devm_pinctrl_register(dev, &bcm2835_pinctrl_desc, pc); if (IS_ERR(pc->pctl_dev)) { gpiochip_remove(&pc->gpio_chip); diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c index 54dad89fc9bf..260908480075 100644 --- a/drivers/pinctrl/devicetree.c +++ b/drivers/pinctrl/devicetree.c @@ -253,3 +253,147 @@ err: pinctrl_dt_free_maps(p); return ret; } + +/* + * For pinctrl binding, typically #pinctrl-cells is for the pin controller + * device, so either parent or grandparent. See pinctrl-bindings.txt. + */ +static int pinctrl_find_cells_size(const struct device_node *np) +{ + const char *cells_name = "#pinctrl-cells"; + int cells_size, error; + + error = of_property_read_u32(np->parent, cells_name, &cells_size); + if (error) { + error = of_property_read_u32(np->parent->parent, + cells_name, &cells_size); + if (error) + return -ENOENT; + } + + return cells_size; +} + +/** + * pinctrl_get_list_and_count - Gets the list and it's cell size and number + * @np: pointer to device node with the property + * @list_name: property that contains the list + * @list: pointer for the list found + * @cells_size: pointer for the cell size found + * @nr_elements: pointer for the number of elements found + * + * Typically np is a single pinctrl entry containing the list. + */ +static int pinctrl_get_list_and_count(const struct device_node *np, + const char *list_name, + const __be32 **list, + int *cells_size, + int *nr_elements) +{ + int size; + + *cells_size = 0; + *nr_elements = 0; + + *list = of_get_property(np, list_name, &size); + if (!*list) + return -ENOENT; + + *cells_size = pinctrl_find_cells_size(np); + if (*cells_size < 0) + return -ENOENT; + + /* First element is always the index within the pinctrl device */ + *nr_elements = (size / sizeof(**list)) / (*cells_size + 1); + + return 0; +} + +/** + * pinctrl_count_index_with_args - Count number of elements in a pinctrl entry + * @np: pointer to device node with the property + * @list_name: property that contains the list + * + * Counts the number of elements in a pinctrl array consisting of an index + * within the controller and a number of u32 entries specified for each + * entry. Note that device_node is always for the parent pin controller device. + */ +int pinctrl_count_index_with_args(const struct device_node *np, + const char *list_name) +{ + const __be32 *list; + int size, nr_cells, error; + + error = pinctrl_get_list_and_count(np, list_name, &list, + &nr_cells, &size); + if (error) + return error; + + return size; +} +EXPORT_SYMBOL_GPL(pinctrl_count_index_with_args); + +/** + * pinctrl_copy_args - Populates of_phandle_args based on index + * @np: pointer to device node with the property + * @list: pointer to a list with the elements + * @index: entry within the list of elements + * @nr_cells: number of cells in the list + * @nr_elem: number of elements for each entry in the list + * @out_args: returned values + * + * Populates the of_phandle_args based on the index in the list. + */ +static int pinctrl_copy_args(const struct device_node *np, + const __be32 *list, + int index, int nr_cells, int nr_elem, + struct of_phandle_args *out_args) +{ + int i; + + memset(out_args, 0, sizeof(*out_args)); + out_args->np = (struct device_node *)np; + out_args->args_count = nr_cells + 1; + + if (index >= nr_elem) + return -EINVAL; + + list += index * (nr_cells + 1); + + for (i = 0; i < nr_cells + 1; i++) + out_args->args[i] = be32_to_cpup(list++); + + return 0; +} + +/** + * pinctrl_parse_index_with_args - Find a node pointed by index in a list + * @np: pointer to device node with the property + * @list_name: property that contains the list + * @index: index within the list + * @out_arts: entries in the list pointed by index + * + * Finds the selected element in a pinctrl array consisting of an index + * within the controller and a number of u32 entries specified for each + * entry. Note that device_node is always for the parent pin controller device. + */ +int pinctrl_parse_index_with_args(const struct device_node *np, + const char *list_name, int index, + struct of_phandle_args *out_args) +{ + const __be32 *list; + int nr_elem, nr_cells, error; + + error = pinctrl_get_list_and_count(np, list_name, &list, + &nr_cells, &nr_elem); + if (error || !nr_cells) + return error; + + error = pinctrl_copy_args(np, list, index, nr_cells, nr_elem, + out_args); + if (error) + return error; + + return 0; +} +EXPORT_SYMBOL_GPL(pinctrl_parse_index_with_args); diff --git a/drivers/pinctrl/devicetree.h b/drivers/pinctrl/devicetree.h index 760bc4960f58..c2d1a5505850 100644 --- a/drivers/pinctrl/devicetree.h +++ b/drivers/pinctrl/devicetree.h @@ -16,11 +16,20 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +struct of_phandle_args; + #ifdef CONFIG_OF void pinctrl_dt_free_maps(struct pinctrl *p); int pinctrl_dt_to_map(struct pinctrl *p); +int pinctrl_count_index_with_args(const struct device_node *np, + const char *list_name); + +int pinctrl_parse_index_with_args(const struct device_node *np, + const char *list_name, int index, + struct of_phandle_args *out_args); + #else static inline int pinctrl_dt_to_map(struct pinctrl *p) @@ -32,4 +41,18 @@ static inline void pinctrl_dt_free_maps(struct pinctrl *p) { } +static inline int pinctrl_count_index_with_args(const struct device_node *np, + const char *list_name) +{ + return -ENODEV; +} + +static inline int +pinctrl_parse_index_with_args(const struct device_node *np, + const char *list_name, int index, + struct of_phandle_args *out_args) +{ + return -ENODEV; +} + #endif diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c index 79c4e14a5a75..5ef7e875b50e 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx.c +++ b/drivers/pinctrl/freescale/pinctrl-imx.c @@ -778,10 +778,10 @@ int imx_pinctrl_probe(struct platform_device *pdev, imx_pinctrl_desc->name = dev_name(&pdev->dev); imx_pinctrl_desc->pins = info->pins; imx_pinctrl_desc->npins = info->npins; - imx_pinctrl_desc->pctlops = &imx_pctrl_ops, - imx_pinctrl_desc->pmxops = &imx_pmx_ops, - imx_pinctrl_desc->confops = &imx_pinconf_ops, - imx_pinctrl_desc->owner = THIS_MODULE, + imx_pinctrl_desc->pctlops = &imx_pctrl_ops; + imx_pinctrl_desc->pmxops = &imx_pmx_ops; + imx_pinctrl_desc->confops = &imx_pinconf_ops; + imx_pinctrl_desc->owner = THIS_MODULE; ret = imx_pinctrl_probe_dt(pdev, info); if (ret) { diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index 71bbeb9321ba..37300634b7d2 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -1703,7 +1703,7 @@ static int byt_gpio_probe(struct byt_gpio *vg) if (irq_rc && irq_rc->start) { byt_gpio_irq_init_hw(vg); ret = gpiochip_irqchip_add(gc, &byt_irqchip, 0, - handle_simple_irq, IRQ_TYPE_NONE); + handle_bad_irq, IRQ_TYPE_NONE); if (ret) { dev_err(&vg->pdev->dev, "failed to add irqchip\n"); goto fail; diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index c43b1e9a06af..5e66860a5e67 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -762,7 +762,7 @@ static void chv_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, seq_printf(s, "mode %d ", mode); } - seq_printf(s, "ctrl0 0x%08x ctrl1 0x%08x", ctrl0, ctrl1); + seq_printf(s, "0x%08x 0x%08x", ctrl0, ctrl1); if (locked) seq_puts(s, " [LOCKED]"); diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 01443762e570..1e139672f1af 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -911,7 +911,7 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq) } ret = gpiochip_irqchip_add(&pctrl->chip, &intel_gpio_irqchip, 0, - handle_simple_irq, IRQ_TYPE_NONE); + handle_bad_irq, IRQ_TYPE_NONE); if (ret) { dev_err(pctrl->dev, "failed to add irqchip\n"); goto fail; diff --git a/drivers/pinctrl/intel/pinctrl-merrifield.c b/drivers/pinctrl/intel/pinctrl-merrifield.c index 7826c7f0cb7c..b21896126f76 100644 --- a/drivers/pinctrl/intel/pinctrl-merrifield.c +++ b/drivers/pinctrl/intel/pinctrl-merrifield.c @@ -814,10 +814,51 @@ static int mrfld_config_set(struct pinctrl_dev *pctldev, unsigned int pin, return 0; } +static int mrfld_config_group_get(struct pinctrl_dev *pctldev, + unsigned int group, unsigned long *config) +{ + const unsigned int *pins; + unsigned int npins; + int ret; + + ret = mrfld_get_group_pins(pctldev, group, &pins, &npins); + if (ret) + return ret; + + ret = mrfld_config_get(pctldev, pins[0], config); + if (ret) + return ret; + + return 0; +} + +static int mrfld_config_group_set(struct pinctrl_dev *pctldev, + unsigned int group, unsigned long *configs, + unsigned int num_configs) +{ + const unsigned int *pins; + unsigned int npins; + int i, ret; + + ret = mrfld_get_group_pins(pctldev, group, &pins, &npins); + if (ret) + return ret; + + for (i = 0; i < npins; i++) { + ret = mrfld_config_set(pctldev, pins[i], configs, num_configs); + if (ret) + return ret; + } + + return 0; +} + static const struct pinconf_ops mrfld_pinconf_ops = { .is_generic = true, .pin_config_get = mrfld_config_get, .pin_config_set = mrfld_config_set, + .pin_config_group_get = mrfld_config_group_get, + .pin_config_group_set = mrfld_config_group_set, }; static const struct pinctrl_desc mrfld_pinctrl_desc = { diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6397.c b/drivers/pinctrl/mediatek/pinctrl-mt6397.c index 6eccb85c02cd..afcede7e2222 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt6397.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt6397.c @@ -64,8 +64,4 @@ static struct platform_driver mtk_pinctrl_driver = { }, }; -static int __init mtk_pinctrl_init(void) -{ - return platform_driver_register(&mtk_pinctrl_driver); -} -device_initcall(mtk_pinctrl_init); +builtin_platform_driver(mtk_pinctrl_driver); diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-mt8173.h b/drivers/pinctrl/mediatek/pinctrl-mtk-mt8173.h index 13e5b68bfe1b..9b018fdbeb51 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-mt8173.h +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-mt8173.h @@ -201,7 +201,7 @@ static const struct mtk_desc_pin mtk_pins_mt8173[] = { MTK_PIN( PINCTRL_PIN(16, "IDDIG"), NULL, "mt8173", - MTK_EINT_FUNCTION(0, 16), + MTK_EINT_FUNCTION(1, 16), MTK_FUNCTION(0, "GPIO16"), MTK_FUNCTION(1, "IDDIG"), MTK_FUNCTION(2, "CMFLASH"), diff --git a/drivers/pinctrl/meson/Makefile b/drivers/pinctrl/meson/Makefile index 24434f139947..27c5b5126008 100644 --- a/drivers/pinctrl/meson/Makefile +++ b/drivers/pinctrl/meson/Makefile @@ -1,2 +1,3 @@ -obj-y += pinctrl-meson8.o pinctrl-meson8b.o pinctrl-meson-gxbb.o +obj-y += pinctrl-meson8.o pinctrl-meson8b.o +obj-y += pinctrl-meson-gxbb.o pinctrl-meson-gxl.o obj-y += pinctrl-meson.o diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxl.c b/drivers/pinctrl/meson/pinctrl-meson-gxl.c new file mode 100644 index 000000000000..25694f7094c7 --- /dev/null +++ b/drivers/pinctrl/meson/pinctrl-meson-gxl.c @@ -0,0 +1,589 @@ +/* + * Pin controller and GPIO driver for Amlogic Meson GXL. + * + * Copyright (C) 2016 Endless Mobile, Inc. + * Author: Carlo Caione <carlo@endlessm.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <dt-bindings/gpio/meson-gxl-gpio.h> +#include "pinctrl-meson.h" + +#define EE_OFF 10 + +static const struct pinctrl_pin_desc meson_gxl_periphs_pins[] = { + MESON_PIN(GPIOZ_0, EE_OFF), + MESON_PIN(GPIOZ_1, EE_OFF), + MESON_PIN(GPIOZ_2, EE_OFF), + MESON_PIN(GPIOZ_3, EE_OFF), + MESON_PIN(GPIOZ_4, EE_OFF), + MESON_PIN(GPIOZ_5, EE_OFF), + MESON_PIN(GPIOZ_6, EE_OFF), + MESON_PIN(GPIOZ_7, EE_OFF), + MESON_PIN(GPIOZ_8, EE_OFF), + MESON_PIN(GPIOZ_9, EE_OFF), + MESON_PIN(GPIOZ_10, EE_OFF), + MESON_PIN(GPIOZ_11, EE_OFF), + MESON_PIN(GPIOZ_12, EE_OFF), + MESON_PIN(GPIOZ_13, EE_OFF), + MESON_PIN(GPIOZ_14, EE_OFF), + MESON_PIN(GPIOZ_15, EE_OFF), + + MESON_PIN(GPIOH_0, EE_OFF), + MESON_PIN(GPIOH_1, EE_OFF), + MESON_PIN(GPIOH_2, EE_OFF), + MESON_PIN(GPIOH_3, EE_OFF), + MESON_PIN(GPIOH_4, EE_OFF), + MESON_PIN(GPIOH_5, EE_OFF), + MESON_PIN(GPIOH_6, EE_OFF), + MESON_PIN(GPIOH_7, EE_OFF), + MESON_PIN(GPIOH_8, EE_OFF), + MESON_PIN(GPIOH_9, EE_OFF), + + MESON_PIN(BOOT_0, EE_OFF), + MESON_PIN(BOOT_1, EE_OFF), + MESON_PIN(BOOT_2, EE_OFF), + MESON_PIN(BOOT_3, EE_OFF), + MESON_PIN(BOOT_4, EE_OFF), + MESON_PIN(BOOT_5, EE_OFF), + MESON_PIN(BOOT_6, EE_OFF), + MESON_PIN(BOOT_7, EE_OFF), + MESON_PIN(BOOT_8, EE_OFF), + MESON_PIN(BOOT_9, EE_OFF), + MESON_PIN(BOOT_10, EE_OFF), + MESON_PIN(BOOT_11, EE_OFF), + MESON_PIN(BOOT_12, EE_OFF), + MESON_PIN(BOOT_13, EE_OFF), + MESON_PIN(BOOT_14, EE_OFF), + MESON_PIN(BOOT_15, EE_OFF), + + MESON_PIN(CARD_0, EE_OFF), + MESON_PIN(CARD_1, EE_OFF), + MESON_PIN(CARD_2, EE_OFF), + MESON_PIN(CARD_3, EE_OFF), + MESON_PIN(CARD_4, EE_OFF), + MESON_PIN(CARD_5, EE_OFF), + MESON_PIN(CARD_6, EE_OFF), + + MESON_PIN(GPIODV_0, EE_OFF), + MESON_PIN(GPIODV_1, EE_OFF), + MESON_PIN(GPIODV_2, EE_OFF), + MESON_PIN(GPIODV_3, EE_OFF), + MESON_PIN(GPIODV_4, EE_OFF), + MESON_PIN(GPIODV_5, EE_OFF), + MESON_PIN(GPIODV_6, EE_OFF), + MESON_PIN(GPIODV_7, EE_OFF), + MESON_PIN(GPIODV_8, EE_OFF), + MESON_PIN(GPIODV_9, EE_OFF), + MESON_PIN(GPIODV_10, EE_OFF), + MESON_PIN(GPIODV_11, EE_OFF), + MESON_PIN(GPIODV_12, EE_OFF), + MESON_PIN(GPIODV_13, EE_OFF), + MESON_PIN(GPIODV_14, EE_OFF), + MESON_PIN(GPIODV_15, EE_OFF), + MESON_PIN(GPIODV_16, EE_OFF), + MESON_PIN(GPIODV_17, EE_OFF), + MESON_PIN(GPIODV_19, EE_OFF), + MESON_PIN(GPIODV_20, EE_OFF), + MESON_PIN(GPIODV_21, EE_OFF), + MESON_PIN(GPIODV_22, EE_OFF), + MESON_PIN(GPIODV_23, EE_OFF), + MESON_PIN(GPIODV_24, EE_OFF), + MESON_PIN(GPIODV_25, EE_OFF), + MESON_PIN(GPIODV_26, EE_OFF), + MESON_PIN(GPIODV_27, EE_OFF), + MESON_PIN(GPIODV_28, EE_OFF), + MESON_PIN(GPIODV_29, EE_OFF), + + MESON_PIN(GPIOX_0, EE_OFF), + MESON_PIN(GPIOX_1, EE_OFF), + MESON_PIN(GPIOX_2, EE_OFF), + MESON_PIN(GPIOX_3, EE_OFF), + MESON_PIN(GPIOX_4, EE_OFF), + MESON_PIN(GPIOX_5, EE_OFF), + MESON_PIN(GPIOX_6, EE_OFF), + MESON_PIN(GPIOX_7, EE_OFF), + MESON_PIN(GPIOX_8, EE_OFF), + MESON_PIN(GPIOX_9, EE_OFF), + MESON_PIN(GPIOX_10, EE_OFF), + MESON_PIN(GPIOX_11, EE_OFF), + MESON_PIN(GPIOX_12, EE_OFF), + MESON_PIN(GPIOX_13, EE_OFF), + MESON_PIN(GPIOX_14, EE_OFF), + MESON_PIN(GPIOX_15, EE_OFF), + MESON_PIN(GPIOX_16, EE_OFF), + MESON_PIN(GPIOX_17, EE_OFF), + MESON_PIN(GPIOX_18, EE_OFF), + + MESON_PIN(GPIOCLK_0, EE_OFF), + MESON_PIN(GPIOCLK_1, EE_OFF), + + MESON_PIN(GPIO_TEST_N, EE_OFF), +}; + +static const unsigned int emmc_nand_d07_pins[] = { + PIN(BOOT_0, EE_OFF), PIN(BOOT_1, EE_OFF), PIN(BOOT_2, EE_OFF), + PIN(BOOT_3, EE_OFF), PIN(BOOT_4, EE_OFF), PIN(BOOT_5, EE_OFF), + PIN(BOOT_6, EE_OFF), PIN(BOOT_7, EE_OFF), +}; +static const unsigned int emmc_clk_pins[] = { PIN(BOOT_8, EE_OFF) }; +static const unsigned int emmc_cmd_pins[] = { PIN(BOOT_10, EE_OFF) }; +static const unsigned int emmc_ds_pins[] = { PIN(BOOT_15, EE_OFF) }; + +static const unsigned int sdcard_d0_pins[] = { PIN(CARD_1, EE_OFF) }; +static const unsigned int sdcard_d1_pins[] = { PIN(CARD_0, EE_OFF) }; +static const unsigned int sdcard_d2_pins[] = { PIN(CARD_5, EE_OFF) }; +static const unsigned int sdcard_d3_pins[] = { PIN(CARD_4, EE_OFF) }; +static const unsigned int sdcard_cmd_pins[] = { PIN(CARD_3, EE_OFF) }; +static const unsigned int sdcard_clk_pins[] = { PIN(CARD_2, EE_OFF) }; + +static const unsigned int sdio_d0_pins[] = { PIN(GPIOX_0, EE_OFF) }; +static const unsigned int sdio_d1_pins[] = { PIN(GPIOX_1, EE_OFF) }; +static const unsigned int sdio_d2_pins[] = { PIN(GPIOX_2, EE_OFF) }; +static const unsigned int sdio_d3_pins[] = { PIN(GPIOX_3, EE_OFF) }; +static const unsigned int sdio_cmd_pins[] = { PIN(GPIOX_4, EE_OFF) }; +static const unsigned int sdio_clk_pins[] = { PIN(GPIOX_5, EE_OFF) }; +static const unsigned int sdio_irq_pins[] = { PIN(GPIOX_7, EE_OFF) }; + +static const unsigned int nand_ce0_pins[] = { PIN(BOOT_8, EE_OFF) }; +static const unsigned int nand_ce1_pins[] = { PIN(BOOT_9, EE_OFF) }; +static const unsigned int nand_rb0_pins[] = { PIN(BOOT_10, EE_OFF) }; +static const unsigned int nand_ale_pins[] = { PIN(BOOT_11, EE_OFF) }; +static const unsigned int nand_cle_pins[] = { PIN(BOOT_12, EE_OFF) }; +static const unsigned int nand_wen_clk_pins[] = { PIN(BOOT_13, EE_OFF) }; +static const unsigned int nand_ren_wr_pins[] = { PIN(BOOT_14, EE_OFF) }; +static const unsigned int nand_dqs_pins[] = { PIN(BOOT_15, EE_OFF) }; + +static const unsigned int uart_tx_a_pins[] = { PIN(GPIOX_12, EE_OFF) }; +static const unsigned int uart_rx_a_pins[] = { PIN(GPIOX_13, EE_OFF) }; +static const unsigned int uart_cts_a_pins[] = { PIN(GPIOX_14, EE_OFF) }; +static const unsigned int uart_rts_a_pins[] = { PIN(GPIOX_15, EE_OFF) }; + +static const unsigned int uart_tx_b_pins[] = { PIN(GPIODV_24, EE_OFF) }; +static const unsigned int uart_rx_b_pins[] = { PIN(GPIODV_25, EE_OFF) }; + +static const unsigned int uart_tx_c_pins[] = { PIN(GPIOX_8, EE_OFF) }; +static const unsigned int uart_rx_c_pins[] = { PIN(GPIOX_9, EE_OFF) }; + +static const unsigned int i2c_sck_a_pins[] = { PIN(GPIODV_25, EE_OFF) }; +static const unsigned int i2c_sda_a_pins[] = { PIN(GPIODV_24, EE_OFF) }; + +static const unsigned int i2c_sck_b_pins[] = { PIN(GPIODV_27, EE_OFF) }; +static const unsigned int i2c_sda_b_pins[] = { PIN(GPIODV_26, EE_OFF) }; + +static const unsigned int i2c_sck_c_pins[] = { PIN(GPIODV_29, EE_OFF) }; +static const unsigned int i2c_sda_c_pins[] = { PIN(GPIODV_28, EE_OFF) }; + +static const unsigned int eth_mdio_pins[] = { PIN(GPIOZ_0, EE_OFF) }; +static const unsigned int eth_mdc_pins[] = { PIN(GPIOZ_1, EE_OFF) }; +static const unsigned int eth_clk_rx_clk_pins[] = { PIN(GPIOZ_2, EE_OFF) }; +static const unsigned int eth_rx_dv_pins[] = { PIN(GPIOZ_3, EE_OFF) }; +static const unsigned int eth_rxd0_pins[] = { PIN(GPIOZ_4, EE_OFF) }; +static const unsigned int eth_rxd1_pins[] = { PIN(GPIOZ_5, EE_OFF) }; +static const unsigned int eth_rxd2_pins[] = { PIN(GPIOZ_6, EE_OFF) }; +static const unsigned int eth_rxd3_pins[] = { PIN(GPIOZ_7, EE_OFF) }; +static const unsigned int eth_rgmii_tx_clk_pins[] = { PIN(GPIOZ_8, EE_OFF) }; +static const unsigned int eth_tx_en_pins[] = { PIN(GPIOZ_9, EE_OFF) }; +static const unsigned int eth_txd0_pins[] = { PIN(GPIOZ_10, EE_OFF) }; +static const unsigned int eth_txd1_pins[] = { PIN(GPIOZ_11, EE_OFF) }; +static const unsigned int eth_txd2_pins[] = { PIN(GPIOZ_12, EE_OFF) }; +static const unsigned int eth_txd3_pins[] = { PIN(GPIOZ_13, EE_OFF) }; + +static const unsigned int pwm_e_pins[] = { PIN(GPIOX_16, EE_OFF) }; + +static const struct pinctrl_pin_desc meson_gxl_aobus_pins[] = { + MESON_PIN(GPIOAO_0, 0), + MESON_PIN(GPIOAO_1, 0), + MESON_PIN(GPIOAO_2, 0), + MESON_PIN(GPIOAO_3, 0), + MESON_PIN(GPIOAO_4, 0), + MESON_PIN(GPIOAO_5, 0), + MESON_PIN(GPIOAO_6, 0), + MESON_PIN(GPIOAO_7, 0), + MESON_PIN(GPIOAO_8, 0), + MESON_PIN(GPIOAO_9, 0), +}; + +static const unsigned int uart_tx_ao_a_pins[] = { PIN(GPIOAO_0, 0) }; +static const unsigned int uart_rx_ao_a_pins[] = { PIN(GPIOAO_1, 0) }; +static const unsigned int uart_cts_ao_a_pins[] = { PIN(GPIOAO_2, 0) }; +static const unsigned int uart_rts_ao_a_pins[] = { PIN(GPIOAO_3, 0) }; +static const unsigned int uart_tx_ao_b_pins[] = { PIN(GPIOAO_0, 0) }; +static const unsigned int uart_rx_ao_b_pins[] = { PIN(GPIOAO_1, 0), + PIN(GPIOAO_5, 0) }; +static const unsigned int uart_cts_ao_b_pins[] = { PIN(GPIOAO_2, 0) }; +static const unsigned int uart_rts_ao_b_pins[] = { PIN(GPIOAO_3, 0) }; + +static const unsigned int remote_input_ao_pins[] = {PIN(GPIOAO_7, 0) }; + +static struct meson_pmx_group meson_gxl_periphs_groups[] = { + GPIO_GROUP(GPIOZ_0, EE_OFF), + GPIO_GROUP(GPIOZ_1, EE_OFF), + GPIO_GROUP(GPIOZ_2, EE_OFF), + GPIO_GROUP(GPIOZ_3, EE_OFF), + GPIO_GROUP(GPIOZ_4, EE_OFF), + GPIO_GROUP(GPIOZ_5, EE_OFF), + GPIO_GROUP(GPIOZ_6, EE_OFF), + GPIO_GROUP(GPIOZ_7, EE_OFF), + GPIO_GROUP(GPIOZ_8, EE_OFF), + GPIO_GROUP(GPIOZ_9, EE_OFF), + GPIO_GROUP(GPIOZ_10, EE_OFF), + GPIO_GROUP(GPIOZ_11, EE_OFF), + GPIO_GROUP(GPIOZ_12, EE_OFF), + GPIO_GROUP(GPIOZ_13, EE_OFF), + GPIO_GROUP(GPIOZ_14, EE_OFF), + GPIO_GROUP(GPIOZ_15, EE_OFF), + + GPIO_GROUP(GPIOH_0, EE_OFF), + GPIO_GROUP(GPIOH_1, EE_OFF), + GPIO_GROUP(GPIOH_2, EE_OFF), + GPIO_GROUP(GPIOH_3, EE_OFF), + GPIO_GROUP(GPIOH_4, EE_OFF), + GPIO_GROUP(GPIOH_5, EE_OFF), + GPIO_GROUP(GPIOH_6, EE_OFF), + GPIO_GROUP(GPIOH_7, EE_OFF), + GPIO_GROUP(GPIOH_8, EE_OFF), + GPIO_GROUP(GPIOH_9, EE_OFF), + + GPIO_GROUP(BOOT_0, EE_OFF), + GPIO_GROUP(BOOT_1, EE_OFF), + GPIO_GROUP(BOOT_2, EE_OFF), + GPIO_GROUP(BOOT_3, EE_OFF), + GPIO_GROUP(BOOT_4, EE_OFF), + GPIO_GROUP(BOOT_5, EE_OFF), + GPIO_GROUP(BOOT_6, EE_OFF), + GPIO_GROUP(BOOT_7, EE_OFF), + GPIO_GROUP(BOOT_8, EE_OFF), + GPIO_GROUP(BOOT_9, EE_OFF), + GPIO_GROUP(BOOT_10, EE_OFF), + GPIO_GROUP(BOOT_11, EE_OFF), + GPIO_GROUP(BOOT_12, EE_OFF), + GPIO_GROUP(BOOT_13, EE_OFF), + GPIO_GROUP(BOOT_14, EE_OFF), + GPIO_GROUP(BOOT_15, EE_OFF), + + GPIO_GROUP(CARD_0, EE_OFF), + GPIO_GROUP(CARD_1, EE_OFF), + GPIO_GROUP(CARD_2, EE_OFF), + GPIO_GROUP(CARD_3, EE_OFF), + GPIO_GROUP(CARD_4, EE_OFF), + GPIO_GROUP(CARD_5, EE_OFF), + GPIO_GROUP(CARD_6, EE_OFF), + + GPIO_GROUP(GPIODV_0, EE_OFF), + GPIO_GROUP(GPIODV_1, EE_OFF), + GPIO_GROUP(GPIODV_2, EE_OFF), + GPIO_GROUP(GPIODV_3, EE_OFF), + GPIO_GROUP(GPIODV_4, EE_OFF), + GPIO_GROUP(GPIODV_5, EE_OFF), + GPIO_GROUP(GPIODV_6, EE_OFF), + GPIO_GROUP(GPIODV_7, EE_OFF), + GPIO_GROUP(GPIODV_8, EE_OFF), + GPIO_GROUP(GPIODV_9, EE_OFF), + GPIO_GROUP(GPIODV_10, EE_OFF), + GPIO_GROUP(GPIODV_11, EE_OFF), + GPIO_GROUP(GPIODV_12, EE_OFF), + GPIO_GROUP(GPIODV_13, EE_OFF), + GPIO_GROUP(GPIODV_14, EE_OFF), + GPIO_GROUP(GPIODV_15, EE_OFF), + GPIO_GROUP(GPIODV_16, EE_OFF), + GPIO_GROUP(GPIODV_17, EE_OFF), + GPIO_GROUP(GPIODV_19, EE_OFF), + GPIO_GROUP(GPIODV_20, EE_OFF), + GPIO_GROUP(GPIODV_21, EE_OFF), + GPIO_GROUP(GPIODV_22, EE_OFF), + GPIO_GROUP(GPIODV_23, EE_OFF), + GPIO_GROUP(GPIODV_24, EE_OFF), + GPIO_GROUP(GPIODV_25, EE_OFF), + GPIO_GROUP(GPIODV_26, EE_OFF), + GPIO_GROUP(GPIODV_27, EE_OFF), + GPIO_GROUP(GPIODV_28, EE_OFF), + GPIO_GROUP(GPIODV_29, EE_OFF), + + GPIO_GROUP(GPIOX_0, EE_OFF), + GPIO_GROUP(GPIOX_1, EE_OFF), + GPIO_GROUP(GPIOX_2, EE_OFF), + GPIO_GROUP(GPIOX_3, EE_OFF), + GPIO_GROUP(GPIOX_4, EE_OFF), + GPIO_GROUP(GPIOX_5, EE_OFF), + GPIO_GROUP(GPIOX_6, EE_OFF), + GPIO_GROUP(GPIOX_7, EE_OFF), + GPIO_GROUP(GPIOX_8, EE_OFF), + GPIO_GROUP(GPIOX_9, EE_OFF), + GPIO_GROUP(GPIOX_10, EE_OFF), + GPIO_GROUP(GPIOX_11, EE_OFF), + GPIO_GROUP(GPIOX_12, EE_OFF), + GPIO_GROUP(GPIOX_13, EE_OFF), + GPIO_GROUP(GPIOX_14, EE_OFF), + GPIO_GROUP(GPIOX_15, EE_OFF), + GPIO_GROUP(GPIOX_16, EE_OFF), + GPIO_GROUP(GPIOX_17, EE_OFF), + GPIO_GROUP(GPIOX_18, EE_OFF), + + GPIO_GROUP(GPIOCLK_0, EE_OFF), + GPIO_GROUP(GPIOCLK_1, EE_OFF), + + GPIO_GROUP(GPIO_TEST_N, EE_OFF), + + /* Bank X */ + GROUP(sdio_d0, 5, 31), + GROUP(sdio_d1, 5, 30), + GROUP(sdio_d2, 5, 29), + GROUP(sdio_d3, 5, 28), + GROUP(sdio_cmd, 5, 27), + GROUP(sdio_clk, 5, 26), + GROUP(sdio_irq, 5, 24), + GROUP(uart_tx_a, 5, 19), + GROUP(uart_rx_a, 5, 18), + GROUP(uart_cts_a, 5, 17), + GROUP(uart_rts_a, 5, 16), + GROUP(uart_tx_c, 5, 13), + GROUP(uart_rx_c, 5, 12), + GROUP(pwm_e, 5, 15), + + /* Bank Z */ + GROUP(eth_mdio, 4, 22), + GROUP(eth_mdc, 4, 23), + GROUP(eth_clk_rx_clk, 4, 21), + GROUP(eth_rx_dv, 4, 20), + GROUP(eth_rxd0, 4, 19), + GROUP(eth_rxd1, 4, 18), + GROUP(eth_rxd2, 4, 17), + GROUP(eth_rxd3, 4, 16), + GROUP(eth_rgmii_tx_clk, 4, 15), + GROUP(eth_tx_en, 4, 14), + GROUP(eth_txd0, 4, 13), + GROUP(eth_txd1, 4, 12), + GROUP(eth_txd2, 4, 11), + GROUP(eth_txd3, 4, 10), + + /* Bank DV */ + GROUP(uart_tx_b, 2, 16), + GROUP(uart_rx_b, 2, 15), + GROUP(i2c_sck_a, 1, 15), + GROUP(i2c_sda_a, 1, 14), + GROUP(i2c_sck_b, 1, 13), + GROUP(i2c_sda_b, 1, 12), + GROUP(i2c_sck_c, 1, 11), + GROUP(i2c_sda_c, 1, 10), + + /* Bank BOOT */ + GROUP(emmc_nand_d07, 7, 31), + GROUP(emmc_clk, 7, 30), + GROUP(emmc_cmd, 7, 29), + GROUP(emmc_ds, 7, 28), + GROUP(nand_ce0, 7, 7), + GROUP(nand_ce1, 7, 6), + GROUP(nand_rb0, 7, 5), + GROUP(nand_ale, 7, 4), + GROUP(nand_cle, 7, 3), + GROUP(nand_wen_clk, 7, 2), + GROUP(nand_ren_wr, 7, 1), + GROUP(nand_dqs, 7, 0), + + /* Bank CARD */ + GROUP(sdcard_d1, 6, 5), + GROUP(sdcard_d0, 6, 4), + GROUP(sdcard_d3, 6, 1), + GROUP(sdcard_d2, 6, 0), + GROUP(sdcard_cmd, 6, 2), + GROUP(sdcard_clk, 6, 3), +}; + +static struct meson_pmx_group meson_gxl_aobus_groups[] = { + GPIO_GROUP(GPIOAO_0, 0), + GPIO_GROUP(GPIOAO_1, 0), + GPIO_GROUP(GPIOAO_2, 0), + GPIO_GROUP(GPIOAO_3, 0), + GPIO_GROUP(GPIOAO_4, 0), + GPIO_GROUP(GPIOAO_5, 0), + GPIO_GROUP(GPIOAO_6, 0), + GPIO_GROUP(GPIOAO_7, 0), + GPIO_GROUP(GPIOAO_8, 0), + GPIO_GROUP(GPIOAO_9, 0), + + /* bank AO */ + GROUP(uart_tx_ao_b, 0, 26), + GROUP(uart_rx_ao_b, 0, 25), + GROUP(uart_tx_ao_a, 0, 12), + GROUP(uart_rx_ao_a, 0, 11), + GROUP(uart_cts_ao_a, 0, 10), + GROUP(uart_rts_ao_a, 0, 9), + GROUP(uart_cts_ao_b, 0, 8), + GROUP(uart_rts_ao_b, 0, 7), + GROUP(remote_input_ao, 0, 0), +}; + +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", "GPIOZ_11", "GPIOZ_12", "GPIOZ_13", "GPIOZ_14", + "GPIOZ_15", + + "GPIOH_0", "GPIOH_1", "GPIOH_2", "GPIOH_3", "GPIOH_4", + "GPIOH_5", "GPIOH_6", "GPIOH_7", "GPIOH_8", "GPIOH_9", + + "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", + "BOOT_15", + + "CARD_0", "CARD_1", "CARD_2", "CARD_3", "CARD_4", + "CARD_5", "CARD_6", + + "GPIODV_0", "GPIODV_1", "GPIODV_2", "GPIODV_3", "GPIODV_4", + "GPIODV_5", "GPIODV_6", "GPIODV_7", "GPIODV_8", "GPIODV_9", + "GPIODV_10", "GPIODV_11", "GPIODV_12", "GPIODV_13", "GPIODV_14", + "GPIODV_15", "GPIODV_16", "GPIODV_17", "GPIODV_18", "GPIODV_19", + "GPIODV_20", "GPIODV_21", "GPIODV_22", "GPIODV_23", "GPIODV_24", + "GPIODV_25", "GPIODV_26", "GPIODV_27", "GPIODV_28", "GPIODV_29", + + "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", + + "GPIO_TEST_N", +}; + +static const char * const emmc_groups[] = { + "emmc_nand_d07", "emmc_clk", "emmc_cmd", "emmc_ds", +}; + +static const char * const sdcard_groups[] = { + "sdcard_d0", "sdcard_d1", "sdcard_d2", "sdcard_d3", + "sdcard_cmd", "sdcard_clk", +}; + +static const char * const sdio_groups[] = { + "sdio_d0", "sdio_d1", "sdio_d2", "sdio_d3", + "sdio_cmd", "sdio_clk", "sdio_irq", +}; + +static const char * const nand_groups[] = { + "nand_ce0", "nand_ce1", "nand_rb0", "nand_ale", "nand_cle", + "nand_wen_clk", "nand_ren_wr", "nand_dqs", +}; + +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", "uart_rx_b", +}; + +static const char * const uart_c_groups[] = { + "uart_tx_c", "uart_rx_c", +}; + +static const char * const i2c_a_groups[] = { + "i2c_sck_a", "i2c_sda_a", +}; + +static const char * const i2c_b_groups[] = { + "i2c_sck_b", "i2c_sda_b", +}; + +static const char * const i2c_c_groups[] = { + "i2c_sck_c", "i2c_sda_c", +}; + +static const char * const eth_groups[] = { + "eth_mdio", "eth_mdc", "eth_clk_rx_clk", "eth_rx_dv", + "eth_rxd0", "eth_rxd1", "eth_rxd2", "eth_rxd3", + "eth_rgmii_tx_clk", "eth_tx_en", + "eth_txd0", "eth_txd1", "eth_txd2", "eth_txd3", +}; + +static const char * const pwm_e_groups[] = { + "pwm_e", +}; + +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", +}; + +static const char * const uart_ao_groups[] = { + "uart_tx_ao_a", "uart_rx_ao_a", "uart_cts_ao_a", "uart_rts_ao_a", +}; + +static const char * const uart_ao_b_groups[] = { + "uart_tx_ao_b", "uart_rx_ao_b", "uart_cts_ao_b", "uart_rts_ao_b", +}; + +static const char * const remote_input_ao_groups[] = { + "remote_input_ao", +}; + +static struct meson_pmx_func meson_gxl_periphs_functions[] = { + FUNCTION(gpio_periphs), + FUNCTION(emmc), + FUNCTION(sdcard), + FUNCTION(sdio), + FUNCTION(nand), + FUNCTION(uart_a), + FUNCTION(uart_b), + FUNCTION(uart_c), + FUNCTION(i2c_a), + FUNCTION(i2c_b), + FUNCTION(i2c_c), + FUNCTION(eth), + FUNCTION(pwm_e), +}; + +static struct meson_pmx_func meson_gxl_aobus_functions[] = { + FUNCTION(gpio_aobus), + FUNCTION(uart_ao), + FUNCTION(uart_ao_b), + FUNCTION(remote_input_ao), +}; + +static struct meson_bank meson_gxl_periphs_banks[] = { + /* name first last pullen pull dir out in */ + BANK("X", PIN(GPIOX_0, EE_OFF), PIN(GPIOX_18, EE_OFF), 4, 0, 4, 0, 12, 0, 13, 0, 14, 0), + BANK("DV", PIN(GPIODV_0, EE_OFF), PIN(GPIODV_29, EE_OFF), 0, 0, 0, 0, 0, 0, 1, 0, 2, 0), + BANK("H", PIN(GPIOH_0, EE_OFF), PIN(GPIOH_9, EE_OFF), 1, 20, 1, 20, 3, 20, 4, 20, 5, 20), + BANK("Z", PIN(GPIOZ_0, EE_OFF), PIN(GPIOZ_15, EE_OFF), 3, 0, 3, 0, 9, 0, 10, 0, 11, 0), + BANK("CARD", PIN(CARD_0, EE_OFF), PIN(CARD_6, EE_OFF), 2, 20, 2, 20, 6, 20, 7, 20, 8, 20), + BANK("BOOT", PIN(BOOT_0, EE_OFF), PIN(BOOT_15, EE_OFF), 2, 0, 2, 0, 6, 0, 7, 0, 8, 0), + BANK("CLK", PIN(GPIOCLK_0, EE_OFF), PIN(GPIOCLK_1, EE_OFF), 3, 28, 3, 28, 9, 28, 10, 28, 11, 28), +}; + +static struct meson_bank meson_gxl_aobus_banks[] = { + /* name first last pullen pull dir out in */ + BANK("AO", PIN(GPIOAO_0, 0), PIN(GPIOAO_9, 0), 0, 0, 0, 16, 0, 0, 0, 16, 1, 0), +}; + +struct meson_pinctrl_data meson_gxl_periphs_pinctrl_data = { + .name = "periphs-banks", + .pin_base = 10, + .pins = meson_gxl_periphs_pins, + .groups = meson_gxl_periphs_groups, + .funcs = meson_gxl_periphs_functions, + .banks = meson_gxl_periphs_banks, + .num_pins = ARRAY_SIZE(meson_gxl_periphs_pins), + .num_groups = ARRAY_SIZE(meson_gxl_periphs_groups), + .num_funcs = ARRAY_SIZE(meson_gxl_periphs_functions), + .num_banks = ARRAY_SIZE(meson_gxl_periphs_banks), +}; + +struct meson_pinctrl_data meson_gxl_aobus_pinctrl_data = { + .name = "aobus-banks", + .pin_base = 0, + .pins = meson_gxl_aobus_pins, + .groups = meson_gxl_aobus_groups, + .funcs = meson_gxl_aobus_functions, + .banks = meson_gxl_aobus_banks, + .num_pins = ARRAY_SIZE(meson_gxl_aobus_pins), + .num_groups = ARRAY_SIZE(meson_gxl_aobus_groups), + .num_funcs = ARRAY_SIZE(meson_gxl_aobus_functions), + .num_banks = ARRAY_SIZE(meson_gxl_aobus_banks), +}; diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c index 57122eda155a..a579126832af 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.c +++ b/drivers/pinctrl/meson/pinctrl-meson.c @@ -524,6 +524,14 @@ static const struct of_device_id meson_pinctrl_dt_match[] = { .compatible = "amlogic,meson-gxbb-aobus-pinctrl", .data = &meson_gxbb_aobus_pinctrl_data, }, + { + .compatible = "amlogic,meson-gxl-periphs-pinctrl", + .data = &meson_gxl_periphs_pinctrl_data, + }, + { + .compatible = "amlogic,meson-gxl-aobus-pinctrl", + .data = &meson_gxl_aobus_pinctrl_data, + }, { }, }; diff --git a/drivers/pinctrl/meson/pinctrl-meson.h b/drivers/pinctrl/meson/pinctrl-meson.h index 98b5080650c1..1aa871d5431e 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.h +++ b/drivers/pinctrl/meson/pinctrl-meson.h @@ -169,3 +169,5 @@ extern struct meson_pinctrl_data meson8b_cbus_pinctrl_data; extern struct meson_pinctrl_data meson8b_aobus_pinctrl_data; extern struct meson_pinctrl_data meson_gxbb_periphs_pinctrl_data; extern struct meson_pinctrl_data meson_gxbb_aobus_pinctrl_data; +extern struct meson_pinctrl_data meson_gxl_periphs_pinctrl_data; +extern struct meson_pinctrl_data meson_gxl_aobus_pinctrl_data; diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c index 8392083514fb..af4814479eb0 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c @@ -379,13 +379,24 @@ static const unsigned msp0txrx_a_1_pins[] = { DB8500_PIN_AC4, DB8500_PIN_AC3 }; static const unsigned msp0tfstck_a_1_pins[] = { DB8500_PIN_AF3, DB8500_PIN_AE3 }; static const unsigned msp0rfsrck_a_1_pins[] = { DB8500_PIN_AD3, DB8500_PIN_AD4 }; /* Basic pins of the MMC/SD card 0 interface */ -static const unsigned mc0_a_1_pins[] = { DB8500_PIN_AC2, DB8500_PIN_AC1, - DB8500_PIN_AB4, DB8500_PIN_AA3, DB8500_PIN_AA4, DB8500_PIN_AB2, - DB8500_PIN_Y4, DB8500_PIN_Y2, DB8500_PIN_AA2, DB8500_PIN_AA1 }; +static const unsigned mc0_a_1_pins[] = { DB8500_PIN_AC2, /* MC0_CMDDIR */ + DB8500_PIN_AC1, /* MC0_DAT0DIR */ + DB8500_PIN_AB4, /* MC0_DAT2DIR */ + DB8500_PIN_AA3, /* MC0_FBCLK */ + DB8500_PIN_AA4, /* MC0_CLK */ + DB8500_PIN_AB2, /* MC0_CMD */ + DB8500_PIN_Y4, /* MC0_DAT0 */ + DB8500_PIN_Y2, /* MC0_DAT1 */ + DB8500_PIN_AA2, /* MC0_DAT2 */ + DB8500_PIN_AA1 /* MC0_DAT3 */ +}; /* Often only 4 bits are used, then these are not needed (only used for MMC) */ -static const unsigned mc0_dat47_a_1_pins[] = { DB8500_PIN_W2, DB8500_PIN_W3, - DB8500_PIN_V3, DB8500_PIN_V2}; -static const unsigned mc0dat31dir_a_1_pins[] = { DB8500_PIN_AB3 }; +static const unsigned mc0_dat47_a_1_pins[] = { DB8500_PIN_W2, /* MC0_DAT4 */ + DB8500_PIN_W3, /* MC0_DAT5 */ + DB8500_PIN_V3, /* MC0_DAT6 */ + DB8500_PIN_V2 /* MC0_DAT7 */ +}; +static const unsigned mc0dat31dir_a_1_pins[] = { DB8500_PIN_AB3 }; /* MC0_DAT31DIR */ /* MSP1 can only be on these pins, but TXD and RXD can be flipped */ static const unsigned msp1txrx_a_1_pins[] = { DB8500_PIN_AF2, DB8500_PIN_AG2 }; static const unsigned msp1_a_1_pins[] = { DB8500_PIN_AE1, DB8500_PIN_AE2 }; diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c index 5020ae534479..ce3335accb5b 100644 --- a/drivers/pinctrl/pinconf-generic.c +++ b/drivers/pinctrl/pinconf-generic.c @@ -381,7 +381,7 @@ int pinconf_generic_dt_node_to_map(struct pinctrl_dev *pctldev, if (ret < 0) goto exit; - for_each_child_of_node(np_config, np) { + for_each_available_child_of_node(np_config, np) { ret = pinconf_generic_dt_subnode_to_map(pctldev, np, map, &reserved_maps, num_maps, type); if (ret < 0) diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 9f0904185909..569bc28cb909 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -56,6 +56,9 @@ static int gpio_banks; #define DRIVE_STRENGTH_SHIFT 5 #define DRIVE_STRENGTH_MASK 0x3 #define DRIVE_STRENGTH (DRIVE_STRENGTH_MASK << DRIVE_STRENGTH_SHIFT) +#define OUTPUT (1 << 7) +#define OUTPUT_VAL_SHIFT 8 +#define OUTPUT_VAL (0x1 << OUTPUT_VAL_SHIFT) #define DEBOUNCE (1 << 16) #define DEBOUNCE_VAL_SHIFT 17 #define DEBOUNCE_VAL (0x3fff << DEBOUNCE_VAL_SHIFT) @@ -375,6 +378,19 @@ static void at91_mux_set_pullup(void __iomem *pio, unsigned mask, bool on) writel_relaxed(mask, pio + (on ? PIO_PUER : PIO_PUDR)); } +static bool at91_mux_get_output(void __iomem *pio, unsigned int pin, bool *val) +{ + *val = (readl_relaxed(pio + PIO_ODSR) >> pin) & 0x1; + return (readl_relaxed(pio + PIO_OSR) >> pin) & 0x1; +} + +static void at91_mux_set_output(void __iomem *pio, unsigned int mask, + bool is_on, bool val) +{ + writel_relaxed(mask, pio + (val ? PIO_SODR : PIO_CODR)); + writel_relaxed(mask, pio + (is_on ? PIO_OER : PIO_ODR)); +} + static unsigned at91_mux_get_multidrive(void __iomem *pio, unsigned pin) { return (readl_relaxed(pio + PIO_MDSR) >> pin) & 0x1; @@ -848,6 +864,7 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev, void __iomem *pio; unsigned pin; int div; + bool out; *config = 0; dev_dbg(info->dev, "%s:%d, pin_id=%d", __func__, __LINE__, pin_id); @@ -875,6 +892,8 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev, if (info->ops->get_drivestrength) *config |= (info->ops->get_drivestrength(pio, pin) << DRIVE_STRENGTH_SHIFT); + if (at91_mux_get_output(pio, pin, &out)) + *config |= OUTPUT | (out << OUTPUT_VAL_SHIFT); return 0; } @@ -907,6 +926,8 @@ static int at91_pinconf_set(struct pinctrl_dev *pctldev, if (config & PULL_UP && config & PULL_DOWN) return -EINVAL; + at91_mux_set_output(pio, mask, config & OUTPUT, + (config & OUTPUT_VAL) >> OUTPUT_VAL_SHIFT); at91_mux_set_pullup(pio, mask, config & PULL_UP); at91_mux_set_multidrive(pio, mask, config & MULTI_DRIVE); if (info->ops->set_deglitch) diff --git a/drivers/pinctrl/pinctrl-da850-pupd.c b/drivers/pinctrl/pinctrl-da850-pupd.c new file mode 100644 index 000000000000..b36a90a3f3e4 --- /dev/null +++ b/drivers/pinctrl/pinctrl-da850-pupd.c @@ -0,0 +1,210 @@ +/* + * Pinconf driver for TI DA850/OMAP-L138/AM18XX pullup/pulldown groups + * + * Copyright (C) 2016 David Lechner + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include <linux/bitops.h> +#include <linux/device.h> +#include <linux/io.h> +#include <linux/ioport.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/pinctrl/pinconf.h> +#include <linux/pinctrl/pinconf-generic.h> +#include <linux/pinctrl/pinctrl.h> +#include <linux/platform_device.h> + +#define DA850_PUPD_ENA 0x00 +#define DA850_PUPD_SEL 0x04 + +struct da850_pupd_data { + void __iomem *base; + struct pinctrl_desc desc; + struct pinctrl_dev *pinctrl; +}; + +static const char * const da850_pupd_group_names[] = { + "cp0", "cp1", "cp2", "cp3", "cp4", "cp5", "cp6", "cp7", + "cp8", "cp9", "cp10", "cp11", "cp12", "cp13", "cp14", "cp15", + "cp16", "cp17", "cp18", "cp19", "cp20", "cp21", "cp22", "cp23", + "cp24", "cp25", "cp26", "cp27", "cp28", "cp29", "cp30", "cp31", +}; + +static int da850_pupd_get_groups_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(da850_pupd_group_names); +} + +static const char *da850_pupd_get_group_name(struct pinctrl_dev *pctldev, + unsigned int selector) +{ + return da850_pupd_group_names[selector]; +} + +static int da850_pupd_get_group_pins(struct pinctrl_dev *pctldev, + unsigned int selector, + const unsigned int **pins, + unsigned int *num_pins) +{ + *num_pins = 0; + + return 0; +} + +static const struct pinctrl_ops da850_pupd_pctlops = { + .get_groups_count = da850_pupd_get_groups_count, + .get_group_name = da850_pupd_get_group_name, + .get_group_pins = da850_pupd_get_group_pins, + .dt_node_to_map = pinconf_generic_dt_node_to_map_group, + .dt_free_map = pinconf_generic_dt_free_map, +}; + +static int da850_pupd_pin_config_group_get(struct pinctrl_dev *pctldev, + unsigned int selector, + unsigned long *config) +{ + struct da850_pupd_data *data = pinctrl_dev_get_drvdata(pctldev); + enum pin_config_param param = pinconf_to_config_param(*config); + u32 val; + u16 arg; + + val = readl(data->base + DA850_PUPD_ENA); + arg = !!(~val & BIT(selector)); + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + break; + case PIN_CONFIG_BIAS_PULL_UP: + case PIN_CONFIG_BIAS_PULL_DOWN: + if (arg) { + /* bias is disabled */ + arg = 0; + break; + } + val = readl(data->base + DA850_PUPD_SEL); + if (param == PIN_CONFIG_BIAS_PULL_DOWN) + val = ~val; + arg = !!(val & BIT(selector)); + break; + default: + return -EINVAL; + } + + *config = pinconf_to_config_packed(param, arg); + + return 0; +} + +static int da850_pupd_pin_config_group_set(struct pinctrl_dev *pctldev, + unsigned int selector, + unsigned long *configs, + unsigned int num_configs) +{ + struct da850_pupd_data *data = pinctrl_dev_get_drvdata(pctldev); + u32 ena, sel; + enum pin_config_param param; + u16 arg; + int i; + + ena = readl(data->base + DA850_PUPD_ENA); + sel = readl(data->base + DA850_PUPD_SEL); + + 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_BIAS_DISABLE: + ena &= ~BIT(selector); + break; + case PIN_CONFIG_BIAS_PULL_UP: + ena |= BIT(selector); + sel |= BIT(selector); + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + ena |= BIT(selector); + sel &= ~BIT(selector); + break; + default: + return -EINVAL; + } + } + + writel(sel, data->base + DA850_PUPD_SEL); + writel(ena, data->base + DA850_PUPD_ENA); + + return 0; +} + +static const struct pinconf_ops da850_pupd_confops = { + .is_generic = true, + .pin_config_group_get = da850_pupd_pin_config_group_get, + .pin_config_group_set = da850_pupd_pin_config_group_set, +}; + +static int da850_pupd_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct da850_pupd_data *data; + struct resource *res; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + data->base = devm_ioremap_resource(dev, res); + if (IS_ERR(data->base)) { + dev_err(dev, "Could not map resource\n"); + return PTR_ERR(data->base); + } + + data->desc.name = dev_name(dev); + data->desc.pctlops = &da850_pupd_pctlops; + data->desc.confops = &da850_pupd_confops; + data->desc.owner = THIS_MODULE; + + data->pinctrl = devm_pinctrl_register(dev, &data->desc, data); + if (IS_ERR(data->pinctrl)) { + dev_err(dev, "Failed to register pinctrl\n"); + return PTR_ERR(data->pinctrl); + } + + platform_set_drvdata(pdev, data); + + return 0; +} + +static int da850_pupd_remove(struct platform_device *pdev) +{ + return 0; +} + +static const struct of_device_id da850_pupd_of_match[] = { + { .compatible = "ti,da850-pupd" }, + { } +}; + +static struct platform_driver da850_pupd_driver = { + .driver = { + .name = "ti-da850-pupd", + .of_match_table = da850_pupd_of_match, + }, + .probe = da850_pupd_probe, + .remove = da850_pupd_remove, +}; +module_platform_driver(da850_pupd_driver); + +MODULE_AUTHOR("David Lechner <david@lechnology.com>"); +MODULE_DESCRIPTION("TI DA850/OMAP-L138/AM18XX pullup/pulldown configuration"); +MODULE_LICENSE("GPL"); diff --git a/drivers/pinctrl/pinctrl-oxnas.c b/drivers/pinctrl/pinctrl-oxnas.c index 917a7d2535d7..494ec9a7573a 100644 --- a/drivers/pinctrl/pinctrl-oxnas.c +++ b/drivers/pinctrl/pinctrl-oxnas.c @@ -37,15 +37,24 @@ #define GPIO_BANK_START(bank) ((bank) * PINS_PER_BANK) -/* Regmap Offsets */ -#define PINMUX_PRIMARY_SEL0 0x0c -#define PINMUX_SECONDARY_SEL0 0x14 -#define PINMUX_TERTIARY_SEL0 0x8c -#define PINMUX_PRIMARY_SEL1 0x10 -#define PINMUX_SECONDARY_SEL1 0x18 -#define PINMUX_TERTIARY_SEL1 0x90 -#define PINMUX_PULLUP_CTRL0 0xac -#define PINMUX_PULLUP_CTRL1 0xb0 +/* OX810 Regmap Offsets */ +#define PINMUX_810_PRIMARY_SEL0 0x0c +#define PINMUX_810_SECONDARY_SEL0 0x14 +#define PINMUX_810_TERTIARY_SEL0 0x8c +#define PINMUX_810_PRIMARY_SEL1 0x10 +#define PINMUX_810_SECONDARY_SEL1 0x18 +#define PINMUX_810_TERTIARY_SEL1 0x90 +#define PINMUX_810_PULLUP_CTRL0 0xac +#define PINMUX_810_PULLUP_CTRL1 0xb0 + +/* OX820 Regmap Offsets */ +#define PINMUX_820_BANK_OFFSET 0x100000 +#define PINMUX_820_SECONDARY_SEL 0x14 +#define PINMUX_820_TERTIARY_SEL 0x8c +#define PINMUX_820_QUATERNARY_SEL 0x94 +#define PINMUX_820_DEBUG_SEL 0x9c +#define PINMUX_820_ALTERNATIVE_SEL 0xa4 +#define PINMUX_820_PULLUP_CTRL 0xac /* GPIO Registers */ #define INPUT_VALUE 0x00 @@ -87,8 +96,6 @@ struct oxnas_pinctrl { struct regmap *regmap; struct device *dev; struct pinctrl_dev *pctldev; - const struct pinctrl_pin_desc *pins; - unsigned int npins; const struct oxnas_function *functions; unsigned int nfunctions; const struct oxnas_pin_group *groups; @@ -97,7 +104,50 @@ struct oxnas_pinctrl { unsigned int nbanks; }; -static const struct pinctrl_pin_desc oxnas_pins[] = { +struct oxnas_pinctrl_data { + struct pinctrl_desc *desc; + struct oxnas_pinctrl *pctl; +}; + +static const struct pinctrl_pin_desc oxnas_ox810se_pins[] = { + PINCTRL_PIN(0, "gpio0"), + PINCTRL_PIN(1, "gpio1"), + PINCTRL_PIN(2, "gpio2"), + PINCTRL_PIN(3, "gpio3"), + PINCTRL_PIN(4, "gpio4"), + PINCTRL_PIN(5, "gpio5"), + PINCTRL_PIN(6, "gpio6"), + PINCTRL_PIN(7, "gpio7"), + PINCTRL_PIN(8, "gpio8"), + PINCTRL_PIN(9, "gpio9"), + PINCTRL_PIN(10, "gpio10"), + PINCTRL_PIN(11, "gpio11"), + PINCTRL_PIN(12, "gpio12"), + PINCTRL_PIN(13, "gpio13"), + PINCTRL_PIN(14, "gpio14"), + PINCTRL_PIN(15, "gpio15"), + PINCTRL_PIN(16, "gpio16"), + PINCTRL_PIN(17, "gpio17"), + PINCTRL_PIN(18, "gpio18"), + PINCTRL_PIN(19, "gpio19"), + PINCTRL_PIN(20, "gpio20"), + PINCTRL_PIN(21, "gpio21"), + PINCTRL_PIN(22, "gpio22"), + PINCTRL_PIN(23, "gpio23"), + PINCTRL_PIN(24, "gpio24"), + PINCTRL_PIN(25, "gpio25"), + PINCTRL_PIN(26, "gpio26"), + PINCTRL_PIN(27, "gpio27"), + PINCTRL_PIN(28, "gpio28"), + PINCTRL_PIN(29, "gpio29"), + PINCTRL_PIN(30, "gpio30"), + PINCTRL_PIN(31, "gpio31"), + PINCTRL_PIN(32, "gpio32"), + PINCTRL_PIN(33, "gpio33"), + PINCTRL_PIN(34, "gpio34"), +}; + +static const struct pinctrl_pin_desc oxnas_ox820_pins[] = { PINCTRL_PIN(0, "gpio0"), PINCTRL_PIN(1, "gpio1"), PINCTRL_PIN(2, "gpio2"), @@ -133,9 +183,24 @@ static const struct pinctrl_pin_desc oxnas_pins[] = { PINCTRL_PIN(32, "gpio32"), PINCTRL_PIN(33, "gpio33"), PINCTRL_PIN(34, "gpio34"), + PINCTRL_PIN(35, "gpio35"), + PINCTRL_PIN(36, "gpio36"), + PINCTRL_PIN(37, "gpio37"), + PINCTRL_PIN(38, "gpio38"), + PINCTRL_PIN(39, "gpio39"), + PINCTRL_PIN(40, "gpio40"), + PINCTRL_PIN(41, "gpio41"), + PINCTRL_PIN(42, "gpio42"), + PINCTRL_PIN(43, "gpio43"), + PINCTRL_PIN(44, "gpio44"), + PINCTRL_PIN(45, "gpio45"), + PINCTRL_PIN(46, "gpio46"), + PINCTRL_PIN(47, "gpio47"), + PINCTRL_PIN(48, "gpio48"), + PINCTRL_PIN(49, "gpio49"), }; -static const char * const oxnas_fct0_group[] = { +static const char * const oxnas_ox810se_fct0_group[] = { "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7", "gpio8", "gpio9", "gpio10", "gpio11", @@ -147,7 +212,7 @@ static const char * const oxnas_fct0_group[] = { "gpio32", "gpio33", "gpio34" }; -static const char * const oxnas_fct3_group[] = { +static const char * const oxnas_ox810se_fct3_group[] = { "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7", "gpio8", "gpio9", @@ -158,6 +223,40 @@ static const char * const oxnas_fct3_group[] = { "gpio34" }; +static const char * const oxnas_ox820_fct0_group[] = { + "gpio0", "gpio1", "gpio2", "gpio3", + "gpio4", "gpio5", "gpio6", "gpio7", + "gpio8", "gpio9", "gpio10", "gpio11", + "gpio12", "gpio13", "gpio14", "gpio15", + "gpio16", "gpio17", "gpio18", "gpio19", + "gpio20", "gpio21", "gpio22", "gpio23", + "gpio24", "gpio25", "gpio26", "gpio27", + "gpio28", "gpio29", "gpio30", "gpio31", + "gpio32", "gpio33", "gpio34", "gpio35", + "gpio36", "gpio37", "gpio38", "gpio39", + "gpio40", "gpio41", "gpio42", "gpio43", + "gpio44", "gpio45", "gpio46", "gpio47", + "gpio48", "gpio49" +}; + +static const char * const oxnas_ox820_fct1_group[] = { + "gpio3", "gpio4", + "gpio12", "gpio13", "gpio14", "gpio15", + "gpio16", "gpio17", "gpio18", "gpio19", + "gpio20", "gpio21", "gpio22", "gpio23", + "gpio24" +}; + +static const char * const oxnas_ox820_fct4_group[] = { + "gpio5", "gpio6", "gpio7", "gpio8", + "gpio24", "gpio25", "gpio26", "gpio27", + "gpio40", "gpio41", "gpio42", "gpio43" +}; + +static const char * const oxnas_ox820_fct5_group[] = { + "gpio28", "gpio29", "gpio30", "gpio31" +}; + #define FUNCTION(_name, _gr) \ { \ .name = #_name, \ @@ -165,9 +264,16 @@ static const char * const oxnas_fct3_group[] = { .ngroups = ARRAY_SIZE(oxnas_##_gr##_group), \ } -static const struct oxnas_function oxnas_functions[] = { - FUNCTION(gpio, fct0), - FUNCTION(fct3, fct3), +static const struct oxnas_function oxnas_ox810se_functions[] = { + FUNCTION(gpio, ox810se_fct0), + FUNCTION(fct3, ox810se_fct3), +}; + +static const struct oxnas_function oxnas_ox820_functions[] = { + FUNCTION(gpio, ox820_fct0), + FUNCTION(fct1, ox820_fct1), + FUNCTION(fct4, ox820_fct4), + FUNCTION(fct5, ox820_fct5), }; #define OXNAS_PINCTRL_GROUP(_pin, _name, ...) \ @@ -185,7 +291,7 @@ static const struct oxnas_function oxnas_functions[] = { .fct = _fct, \ } -static const struct oxnas_pin_group oxnas_groups[] = { +static const struct oxnas_pin_group oxnas_ox810se_groups[] = { OXNAS_PINCTRL_GROUP(0, gpio0, OXNAS_PINCTRL_FUNCTION(gpio, 0), OXNAS_PINCTRL_FUNCTION(fct3, 3)), @@ -282,6 +388,140 @@ static const struct oxnas_pin_group oxnas_groups[] = { OXNAS_PINCTRL_FUNCTION(fct3, 3)), }; +static const struct oxnas_pin_group oxnas_ox820_groups[] = { + OXNAS_PINCTRL_GROUP(0, gpio0, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(1, gpio1, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(2, gpio2, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(3, gpio3, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct1, 1)), + OXNAS_PINCTRL_GROUP(4, gpio4, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct1, 1)), + OXNAS_PINCTRL_GROUP(5, gpio5, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct4, 4)), + OXNAS_PINCTRL_GROUP(6, gpio6, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct4, 4)), + OXNAS_PINCTRL_GROUP(7, gpio7, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct4, 4)), + OXNAS_PINCTRL_GROUP(8, gpio8, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct4, 4)), + OXNAS_PINCTRL_GROUP(9, gpio9, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(10, gpio10, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(11, gpio11, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(12, gpio12, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct1, 1)), + OXNAS_PINCTRL_GROUP(13, gpio13, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct1, 1)), + OXNAS_PINCTRL_GROUP(14, gpio14, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct1, 1)), + OXNAS_PINCTRL_GROUP(15, gpio15, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct1, 1)), + OXNAS_PINCTRL_GROUP(16, gpio16, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct1, 1)), + OXNAS_PINCTRL_GROUP(17, gpio17, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct1, 1)), + OXNAS_PINCTRL_GROUP(18, gpio18, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct1, 1)), + OXNAS_PINCTRL_GROUP(19, gpio19, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct1, 1)), + OXNAS_PINCTRL_GROUP(20, gpio20, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct1, 1)), + OXNAS_PINCTRL_GROUP(21, gpio21, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct1, 1)), + OXNAS_PINCTRL_GROUP(22, gpio22, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct1, 1)), + OXNAS_PINCTRL_GROUP(23, gpio23, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct1, 1)), + OXNAS_PINCTRL_GROUP(24, gpio24, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct1, 1), + OXNAS_PINCTRL_FUNCTION(fct4, 5)), + OXNAS_PINCTRL_GROUP(25, gpio25, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct4, 4)), + OXNAS_PINCTRL_GROUP(26, gpio26, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct4, 4)), + OXNAS_PINCTRL_GROUP(27, gpio27, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct4, 4)), + OXNAS_PINCTRL_GROUP(28, gpio28, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct5, 5)), + OXNAS_PINCTRL_GROUP(29, gpio29, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct5, 5)), + OXNAS_PINCTRL_GROUP(30, gpio30, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct5, 5)), + OXNAS_PINCTRL_GROUP(31, gpio31, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct5, 5)), + OXNAS_PINCTRL_GROUP(32, gpio32, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(33, gpio33, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(34, gpio34, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(35, gpio35, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(36, gpio36, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(37, gpio37, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(38, gpio38, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(39, gpio39, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(40, gpio40, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct4, 4)), + OXNAS_PINCTRL_GROUP(41, gpio41, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct4, 4)), + OXNAS_PINCTRL_GROUP(42, gpio42, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct4, 4)), + OXNAS_PINCTRL_GROUP(43, gpio43, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct4, 4)), + OXNAS_PINCTRL_GROUP(44, gpio44, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(45, gpio45, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(46, gpio46, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(47, gpio47, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(48, gpio48, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(49, gpio49, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), +}; + static inline struct oxnas_gpio_bank *pctl_to_bank(struct oxnas_pinctrl *pctl, unsigned int pin) { @@ -352,8 +592,8 @@ static int oxnas_pinmux_get_function_groups(struct pinctrl_dev *pctldev, return 0; } -static int oxnas_pinmux_enable(struct pinctrl_dev *pctldev, - unsigned int func, unsigned int group) +static int oxnas_ox810se_pinmux_enable(struct pinctrl_dev *pctldev, + unsigned int func, unsigned int group) { struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); const struct oxnas_pin_group *pg = &pctl->groups[group]; @@ -371,22 +611,22 @@ static int oxnas_pinmux_enable(struct pinctrl_dev *pctldev, regmap_write_bits(pctl->regmap, (pg->bank ? - PINMUX_PRIMARY_SEL1 : - PINMUX_PRIMARY_SEL0), + PINMUX_810_PRIMARY_SEL1 : + PINMUX_810_PRIMARY_SEL0), mask, (functions->fct == 1 ? mask : 0)); regmap_write_bits(pctl->regmap, (pg->bank ? - PINMUX_SECONDARY_SEL1 : - PINMUX_SECONDARY_SEL0), + PINMUX_810_SECONDARY_SEL1 : + PINMUX_810_SECONDARY_SEL0), mask, (functions->fct == 2 ? mask : 0)); regmap_write_bits(pctl->regmap, (pg->bank ? - PINMUX_TERTIARY_SEL1 : - PINMUX_TERTIARY_SEL0), + PINMUX_810_TERTIARY_SEL1 : + PINMUX_810_TERTIARY_SEL0), mask, (functions->fct == 3 ? mask : 0)); @@ -402,9 +642,64 @@ static int oxnas_pinmux_enable(struct pinctrl_dev *pctldev, return -EINVAL; } -static int oxnas_gpio_request_enable(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, - unsigned int offset) +static int oxnas_ox820_pinmux_enable(struct pinctrl_dev *pctldev, + unsigned int func, unsigned int group) +{ + struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + const struct oxnas_pin_group *pg = &pctl->groups[group]; + const struct oxnas_function *pf = &pctl->functions[func]; + const char *fname = pf->name; + struct oxnas_desc_function *functions = pg->functions; + unsigned int offset = (pg->bank ? PINMUX_820_BANK_OFFSET : 0); + u32 mask = BIT(pg->pin); + + while (functions->name) { + if (!strcmp(functions->name, fname)) { + dev_dbg(pctl->dev, + "setting function %s bank %d pin %d fct %d mask %x\n", + fname, pg->bank, pg->pin, + functions->fct, mask); + + regmap_write_bits(pctl->regmap, + offset + PINMUX_820_SECONDARY_SEL, + mask, + (functions->fct == 1 ? + mask : 0)); + regmap_write_bits(pctl->regmap, + offset + PINMUX_820_TERTIARY_SEL, + mask, + (functions->fct == 2 ? + mask : 0)); + regmap_write_bits(pctl->regmap, + offset + PINMUX_820_QUATERNARY_SEL, + mask, + (functions->fct == 3 ? + mask : 0)); + regmap_write_bits(pctl->regmap, + offset + PINMUX_820_DEBUG_SEL, + mask, + (functions->fct == 4 ? + mask : 0)); + regmap_write_bits(pctl->regmap, + offset + PINMUX_820_ALTERNATIVE_SEL, + mask, + (functions->fct == 5 ? + mask : 0)); + + return 0; + } + + functions++; + } + + dev_err(pctl->dev, "cannot mux pin %u to function %u\n", group, func); + + return -EINVAL; +} + +static int oxnas_ox810se_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int offset) { struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); struct oxnas_gpio_bank *bank = gpiochip_get_data(range->gc); @@ -415,18 +710,49 @@ static int oxnas_gpio_request_enable(struct pinctrl_dev *pctldev, regmap_write_bits(pctl->regmap, (bank->id ? - PINMUX_PRIMARY_SEL1 : - PINMUX_PRIMARY_SEL0), + PINMUX_810_PRIMARY_SEL1 : + PINMUX_810_PRIMARY_SEL0), mask, 0); regmap_write_bits(pctl->regmap, (bank->id ? - PINMUX_SECONDARY_SEL1 : - PINMUX_SECONDARY_SEL0), + PINMUX_810_SECONDARY_SEL1 : + PINMUX_810_SECONDARY_SEL0), mask, 0); regmap_write_bits(pctl->regmap, (bank->id ? - PINMUX_TERTIARY_SEL1 : - PINMUX_TERTIARY_SEL0), + PINMUX_810_TERTIARY_SEL1 : + PINMUX_810_TERTIARY_SEL0), + mask, 0); + + return 0; +} + +static int oxnas_ox820_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int offset) +{ + struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + struct oxnas_gpio_bank *bank = gpiochip_get_data(range->gc); + unsigned int bank_offset = (bank->id ? PINMUX_820_BANK_OFFSET : 0); + u32 mask = BIT(offset - bank->gpio_chip.base); + + dev_dbg(pctl->dev, "requesting gpio %d in bank %d (id %d) with mask 0x%x\n", + offset, bank->gpio_chip.base, bank->id, mask); + + regmap_write_bits(pctl->regmap, + bank_offset + PINMUX_820_SECONDARY_SEL, + mask, 0); + regmap_write_bits(pctl->regmap, + bank_offset + PINMUX_820_TERTIARY_SEL, + mask, 0); + regmap_write_bits(pctl->regmap, + bank_offset + PINMUX_820_QUATERNARY_SEL, + mask, 0); + regmap_write_bits(pctl->regmap, + bank_offset + PINMUX_820_DEBUG_SEL, + mask, 0); + regmap_write_bits(pctl->regmap, + bank_offset + PINMUX_820_ALTERNATIVE_SEL, mask, 0); return 0; @@ -498,17 +824,26 @@ static int oxnas_gpio_set_direction(struct pinctrl_dev *pctldev, return 0; } -static const struct pinmux_ops oxnas_pinmux_ops = { +static const struct pinmux_ops oxnas_ox810se_pinmux_ops = { .get_functions_count = oxnas_pinmux_get_functions_count, .get_function_name = oxnas_pinmux_get_function_name, .get_function_groups = oxnas_pinmux_get_function_groups, - .set_mux = oxnas_pinmux_enable, - .gpio_request_enable = oxnas_gpio_request_enable, + .set_mux = oxnas_ox810se_pinmux_enable, + .gpio_request_enable = oxnas_ox810se_gpio_request_enable, .gpio_set_direction = oxnas_gpio_set_direction, }; -static int oxnas_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, - unsigned long *config) +static const struct pinmux_ops oxnas_ox820_pinmux_ops = { + .get_functions_count = oxnas_pinmux_get_functions_count, + .get_function_name = oxnas_pinmux_get_function_name, + .get_function_groups = oxnas_pinmux_get_function_groups, + .set_mux = oxnas_ox820_pinmux_enable, + .gpio_request_enable = oxnas_ox820_gpio_request_enable, + .gpio_set_direction = oxnas_gpio_set_direction, +}; + +static int oxnas_ox810se_pinconf_get(struct pinctrl_dev *pctldev, + unsigned int pin, unsigned long *config) { struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); struct oxnas_gpio_bank *bank = pctl_to_bank(pctl, pin); @@ -521,8 +856,38 @@ static int oxnas_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, case PIN_CONFIG_BIAS_PULL_UP: ret = regmap_read(pctl->regmap, (bank->id ? - PINMUX_PULLUP_CTRL1 : - PINMUX_PULLUP_CTRL0), + PINMUX_810_PULLUP_CTRL1 : + PINMUX_810_PULLUP_CTRL0), + &arg); + if (ret) + return ret; + + arg = !!(arg & mask); + break; + default: + return -ENOTSUPP; + } + + *config = pinconf_to_config_packed(param, arg); + + return 0; +} + +static int oxnas_ox820_pinconf_get(struct pinctrl_dev *pctldev, + unsigned int pin, unsigned long *config) +{ + struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + struct oxnas_gpio_bank *bank = pctl_to_bank(pctl, pin); + unsigned int param = pinconf_to_config_param(*config); + unsigned int bank_offset = (bank->id ? PINMUX_820_BANK_OFFSET : 0); + u32 mask = BIT(pin - bank->gpio_chip.base); + int ret; + u32 arg; + + switch (param) { + case PIN_CONFIG_BIAS_PULL_UP: + ret = regmap_read(pctl->regmap, + bank_offset + PINMUX_820_PULLUP_CTRL, &arg); if (ret) return ret; @@ -538,8 +903,9 @@ static int oxnas_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, return 0; } -static int oxnas_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, - unsigned long *configs, unsigned int num_configs) +static int oxnas_ox810se_pinconf_set(struct pinctrl_dev *pctldev, + unsigned int pin, unsigned long *configs, + unsigned int num_configs) { struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); struct oxnas_gpio_bank *bank = pctl_to_bank(pctl, pin); @@ -561,8 +927,8 @@ static int oxnas_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, dev_dbg(pctl->dev, " pullup\n"); regmap_write_bits(pctl->regmap, (bank->id ? - PINMUX_PULLUP_CTRL1 : - PINMUX_PULLUP_CTRL0), + PINMUX_810_PULLUP_CTRL1 : + PINMUX_810_PULLUP_CTRL0), mask, mask); break; default: @@ -575,18 +941,53 @@ static int oxnas_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, return 0; } -static const struct pinconf_ops oxnas_pinconf_ops = { - .pin_config_get = oxnas_pinconf_get, - .pin_config_set = oxnas_pinconf_set, +static int oxnas_ox820_pinconf_set(struct pinctrl_dev *pctldev, + unsigned int pin, unsigned long *configs, + unsigned int num_configs) +{ + struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + struct oxnas_gpio_bank *bank = pctl_to_bank(pctl, pin); + unsigned int bank_offset = (bank->id ? PINMUX_820_BANK_OFFSET : 0); + unsigned int param; + u32 arg; + unsigned int i; + u32 offset = pin - bank->gpio_chip.base; + u32 mask = BIT(offset); + + dev_dbg(pctl->dev, "setting pin %d bank %d mask 0x%x\n", + pin, bank->gpio_chip.base, mask); + + 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_BIAS_PULL_UP: + dev_dbg(pctl->dev, " pullup\n"); + regmap_write_bits(pctl->regmap, + bank_offset + PINMUX_820_PULLUP_CTRL, + mask, mask); + break; + default: + dev_err(pctl->dev, "Property %u not supported\n", + param); + return -ENOTSUPP; + } + } + + return 0; +} + +static const struct pinconf_ops oxnas_ox810se_pinconf_ops = { + .pin_config_get = oxnas_ox810se_pinconf_get, + .pin_config_set = oxnas_ox810se_pinconf_set, .is_generic = true, }; -static struct pinctrl_desc oxnas_pinctrl_desc = { - .name = "oxnas-pinctrl", - .pctlops = &oxnas_pinctrl_ops, - .pmxops = &oxnas_pinmux_ops, - .confops = &oxnas_pinconf_ops, - .owner = THIS_MODULE, +static const struct pinconf_ops oxnas_ox820_pinconf_ops = { + .pin_config_get = oxnas_ox820_pinconf_get, + .pin_config_set = oxnas_ox820_pinconf_set, + .is_generic = true, }; static void oxnas_gpio_irq_ack(struct irq_data *data) @@ -699,10 +1100,78 @@ static struct oxnas_gpio_bank oxnas_gpio_banks[] = { GPIO_BANK(1), }; +static struct oxnas_pinctrl ox810se_pinctrl = { + .functions = oxnas_ox810se_functions, + .nfunctions = ARRAY_SIZE(oxnas_ox810se_functions), + .groups = oxnas_ox810se_groups, + .ngroups = ARRAY_SIZE(oxnas_ox810se_groups), + .gpio_banks = oxnas_gpio_banks, + .nbanks = ARRAY_SIZE(oxnas_gpio_banks), +}; + +static struct pinctrl_desc oxnas_ox810se_pinctrl_desc = { + .name = "oxnas-pinctrl", + .pins = oxnas_ox810se_pins, + .npins = ARRAY_SIZE(oxnas_ox810se_pins), + .pctlops = &oxnas_pinctrl_ops, + .pmxops = &oxnas_ox810se_pinmux_ops, + .confops = &oxnas_ox810se_pinconf_ops, + .owner = THIS_MODULE, +}; + +static struct oxnas_pinctrl ox820_pinctrl = { + .functions = oxnas_ox820_functions, + .nfunctions = ARRAY_SIZE(oxnas_ox820_functions), + .groups = oxnas_ox820_groups, + .ngroups = ARRAY_SIZE(oxnas_ox820_groups), + .gpio_banks = oxnas_gpio_banks, + .nbanks = ARRAY_SIZE(oxnas_gpio_banks), +}; + +static struct pinctrl_desc oxnas_ox820_pinctrl_desc = { + .name = "oxnas-pinctrl", + .pins = oxnas_ox820_pins, + .npins = ARRAY_SIZE(oxnas_ox820_pins), + .pctlops = &oxnas_pinctrl_ops, + .pmxops = &oxnas_ox820_pinmux_ops, + .confops = &oxnas_ox820_pinconf_ops, + .owner = THIS_MODULE, +}; + +static struct oxnas_pinctrl_data oxnas_ox810se_pinctrl_data = { + .desc = &oxnas_ox810se_pinctrl_desc, + .pctl = &ox810se_pinctrl, +}; + +static struct oxnas_pinctrl_data oxnas_ox820_pinctrl_data = { + .desc = &oxnas_ox820_pinctrl_desc, + .pctl = &ox820_pinctrl, +}; + +static const struct of_device_id oxnas_pinctrl_of_match[] = { + { .compatible = "oxsemi,ox810se-pinctrl", + .data = &oxnas_ox810se_pinctrl_data + }, + { .compatible = "oxsemi,ox820-pinctrl", + .data = &oxnas_ox820_pinctrl_data, + }, + { }, +}; + static int oxnas_pinctrl_probe(struct platform_device *pdev) { + const struct of_device_id *id; + const struct oxnas_pinctrl_data *data; struct oxnas_pinctrl *pctl; + id = of_match_node(oxnas_pinctrl_of_match, pdev->dev.of_node); + if (!id) + return -ENODEV; + + data = id->data; + if (!data || !data->pctl || !data->desc) + return -EINVAL; + pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL); if (!pctl) return -ENOMEM; @@ -716,20 +1185,14 @@ static int oxnas_pinctrl_probe(struct platform_device *pdev) return -ENODEV; } - pctl->pins = oxnas_pins; - pctl->npins = ARRAY_SIZE(oxnas_pins); - pctl->functions = oxnas_functions; - pctl->nfunctions = ARRAY_SIZE(oxnas_functions); - pctl->groups = oxnas_groups; - pctl->ngroups = ARRAY_SIZE(oxnas_groups); - pctl->gpio_banks = oxnas_gpio_banks; - pctl->nbanks = ARRAY_SIZE(oxnas_gpio_banks); - - oxnas_pinctrl_desc.pins = pctl->pins; - oxnas_pinctrl_desc.npins = pctl->npins; + pctl->functions = data->pctl->functions; + pctl->nfunctions = data->pctl->nfunctions; + pctl->groups = data->pctl->groups; + pctl->ngroups = data->pctl->ngroups; + pctl->gpio_banks = data->pctl->gpio_banks; + pctl->nbanks = data->pctl->nbanks; - pctl->pctldev = pinctrl_register(&oxnas_pinctrl_desc, - &pdev->dev, pctl); + pctl->pctldev = pinctrl_register(data->desc, &pdev->dev, pctl); if (IS_ERR(pctl->pctldev)) { dev_err(&pdev->dev, "Failed to register pinctrl device\n"); return PTR_ERR(pctl->pctldev); @@ -805,11 +1268,6 @@ static int oxnas_gpio_probe(struct platform_device *pdev) return 0; } -static const struct of_device_id oxnas_pinctrl_of_match[] = { - { .compatible = "oxsemi,ox810se-pinctrl", }, - { }, -}; - static struct platform_driver oxnas_pinctrl_driver = { .driver = { .name = "oxnas-pinctrl", @@ -821,6 +1279,7 @@ static struct platform_driver oxnas_pinctrl_driver = { static const struct of_device_id oxnas_gpio_of_match[] = { { .compatible = "oxsemi,ox810se-gpio", }, + { .compatible = "oxsemi,ox820-gpio", }, { }, }; diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 49bf7dcb7ed8..08765f58253c 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -59,6 +59,7 @@ #define GPIO_LS_SYNC 0x60 enum rockchip_pinctrl_type { + RK1108, RK2928, RK3066B, RK3188, @@ -624,6 +625,65 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) return ret; } +#define RK1108_PULL_PMU_OFFSET 0x10 +#define RK1108_PULL_OFFSET 0x110 +#define RK1108_PULL_PINS_PER_REG 8 +#define RK1108_PULL_BITS_PER_PIN 2 +#define RK1108_PULL_BANK_STRIDE 16 + +static void rk1108_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + + /* The first 24 pins of the first bank are located in PMU */ + if (bank->bank_num == 0) { + *regmap = info->regmap_pmu; + *reg = RK1108_PULL_PMU_OFFSET; + } else { + *reg = RK1108_PULL_OFFSET; + *regmap = info->regmap_base; + /* correct the offset, as we're starting with the 2nd bank */ + *reg -= 0x10; + *reg += bank->bank_num * RK1108_PULL_BANK_STRIDE; + } + + *reg += ((pin_num / RK1108_PULL_PINS_PER_REG) * 4); + *bit = (pin_num % RK1108_PULL_PINS_PER_REG); + *bit *= RK1108_PULL_BITS_PER_PIN; +} + +#define RK1108_DRV_PMU_OFFSET 0x20 +#define RK1108_DRV_GRF_OFFSET 0x210 +#define RK1108_DRV_BITS_PER_PIN 2 +#define RK1108_DRV_PINS_PER_REG 8 +#define RK1108_DRV_BANK_STRIDE 16 + +static void rk1108_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + + /* The first 24 pins of the first bank are located in PMU */ + if (bank->bank_num == 0) { + *regmap = info->regmap_pmu; + *reg = RK1108_DRV_PMU_OFFSET; + } else { + *regmap = info->regmap_base; + *reg = RK1108_DRV_GRF_OFFSET; + + /* correct the offset, as we're starting with the 2nd bank */ + *reg -= 0x10; + *reg += bank->bank_num * RK1108_DRV_BANK_STRIDE; + } + + *reg += ((pin_num / RK1108_DRV_PINS_PER_REG) * 4); + *bit = pin_num % RK1108_DRV_PINS_PER_REG; + *bit *= RK1108_DRV_BITS_PER_PIN; +} + #define RK2928_PULL_OFFSET 0x118 #define RK2928_PULL_PINS_PER_REG 16 #define RK2928_PULL_BANK_STRIDE 8 @@ -1123,6 +1183,7 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) return !(data & BIT(bit)) ? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT : PIN_CONFIG_BIAS_DISABLE; + case RK1108: case RK3188: case RK3288: case RK3368: @@ -1169,6 +1230,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, spin_unlock_irqrestore(&bank->slock, flags); break; + case RK1108: case RK3188: case RK3288: case RK3368: @@ -1358,6 +1420,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, pull == PIN_CONFIG_BIAS_DISABLE); case RK3066B: return pull ? false : true; + case RK1108: case RK3188: case RK3288: case RK3368: @@ -2455,6 +2518,27 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev) return 0; } +static struct rockchip_pin_bank rk1108_pin_banks[] = { + PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, + IOMUX_SOURCE_PMU, + IOMUX_SOURCE_PMU, + IOMUX_SOURCE_PMU), + PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0), + PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, 0), + PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, 0), +}; + +static struct rockchip_pin_ctrl rk1108_pin_ctrl = { + .pin_banks = rk1108_pin_banks, + .nr_banks = ARRAY_SIZE(rk1108_pin_banks), + .label = "RK1108-GPIO", + .type = RK1108, + .grf_mux_offset = 0x10, + .pmu_mux_offset = 0x0, + .pull_calc_reg = rk1108_calc_pull_reg_and_bit, + .drv_calc_reg = rk1108_calc_drv_reg_and_bit, +}; + static struct rockchip_pin_bank rk2928_pin_banks[] = { PIN_BANK(0, 32, "gpio0"), PIN_BANK(1, 32, "gpio1"), @@ -2684,6 +2768,8 @@ static struct rockchip_pin_ctrl rk3399_pin_ctrl = { }; static const struct of_device_id rockchip_pinctrl_dt_match[] = { + { .compatible = "rockchip,rk1108-pinctrl", + .data = (void *)&rk1108_pin_ctrl }, { .compatible = "rockchip,rk2928-pinctrl", .data = (void *)&rk2928_pin_ctrl }, { .compatible = "rockchip,rk3036-pinctrl", diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index bfdf720db270..a5a0392ab817 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -31,12 +31,10 @@ #include <linux/platform_data/pinctrl-single.h> #include "core.h" +#include "devicetree.h" #include "pinconf.h" #define DRIVER_NAME "pinctrl-single" -#define PCS_MUX_PINS_NAME "pinctrl-single,pins" -#define PCS_MUX_BITS_NAME "pinctrl-single,bits" -#define PCS_REG_NAME_LEN ((sizeof(unsigned long) * 2) + 3) #define PCS_OFF_DISABLED ~0U /** @@ -142,20 +140,6 @@ struct pcs_data { }; /** - * struct pcs_name - register name for a pin - * @name: name of the pinctrl register - * - * REVISIT: We may want to make names optional in the pinctrl - * framework as some drivers may not care about pin names to - * avoid kernel bloat. The pin names can be deciphered by user - * space tools using debugfs based on the register address and - * SoC packaging information. - */ -struct pcs_name { - char name[PCS_REG_NAME_LEN]; -}; - -/** * struct pcs_soc_data - SoC specific settings * @flags: initial SoC specific PCS_FEAT_xxx values * @irq: optional interrupt for the controller @@ -177,8 +161,11 @@ struct pcs_soc_data { * @base: virtual address of the controller * @size: size of the ioremapped area * @dev: device entry + * @np: device tree node * @pctl: pin controller device * @flags: mask of PCS_FEAT_xxx values + * @missing_nr_pinctrl_cells: for legacy binding, may go away + * @socdata: soc specific data * @lock: spinlock for register access * @mutex: mutex protecting the lists * @width: bits per mux register @@ -186,8 +173,8 @@ struct pcs_soc_data { * @fshift: function register shift * @foff: value to turn mux off * @fmax: max number of functions in fmask - * @bits_per_pin:number of bits per pin - * @names: array of register names for pins + * @bits_per_mux: number of bits per mux + * @bits_per_pin: number of bits per pin * @pins: physical pins on the SoC * @pgtree: pingroup index radix tree * @ftree: function index radix tree @@ -208,11 +195,13 @@ struct pcs_device { void __iomem *base; unsigned size; struct device *dev; + struct device_node *np; struct pinctrl_dev *pctl; unsigned flags; #define PCS_QUIRK_SHARED_IRQ (1 << 2) #define PCS_FEAT_IRQ (1 << 1) #define PCS_FEAT_PINCONF (1 << 0) + struct property *missing_nr_pinctrl_cells; struct pcs_soc_data socdata; raw_spinlock_t lock; struct mutex mutex; @@ -223,7 +212,6 @@ struct pcs_device { unsigned fmax; bool bits_per_mux; unsigned bits_per_pin; - struct pcs_name *names; struct pcs_data pins; struct radix_tree_root pgtree; struct radix_tree_root ftree; @@ -354,13 +342,17 @@ static void pcs_pin_dbg_show(struct pinctrl_dev *pctldev, { struct pcs_device *pcs; unsigned val, mux_bytes; + unsigned long offset; + size_t pa; pcs = pinctrl_dev_get_drvdata(pctldev); mux_bytes = pcs->width / BITS_PER_BYTE; - val = pcs->read(pcs->base + pin * mux_bytes); + offset = pin * mux_bytes; + val = pcs->read(pcs->base + offset); + pa = pcs->res->start + offset; - seq_printf(s, "%08x %s " , val, DRIVER_NAME); + seq_printf(s, "%zx %08x %s ", pa, val, DRIVER_NAME); } static void pcs_dt_free_map(struct pinctrl_dev *pctldev, @@ -763,7 +755,6 @@ static int pcs_add_pin(struct pcs_device *pcs, unsigned offset, { struct pcs_soc_data *pcs_soc = &pcs->socdata; struct pinctrl_pin_desc *pin; - struct pcs_name *pn; int i; i = pcs->pins.cur; @@ -786,10 +777,6 @@ static int pcs_add_pin(struct pcs_device *pcs, unsigned offset, } pin = &pcs->pins.pa[i]; - pn = &pcs->names[i]; - sprintf(pn->name, "%lx.%u", - (unsigned long)pcs->res->start + offset, pin_pos); - pin->name = pn->name; pin->number = i; pcs->pins.cur++; @@ -827,12 +814,6 @@ static int pcs_allocate_pin_table(struct pcs_device *pcs) if (!pcs->pins.pa) return -ENOMEM; - pcs->names = devm_kzalloc(pcs->dev, - sizeof(struct pcs_name) * nr_pins, - GFP_KERNEL); - if (!pcs->names) - return -ENOMEM; - pcs->desc.pins = pcs->pins.pa; pcs->desc.npins = nr_pins; @@ -1146,21 +1127,17 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs, unsigned *num_maps, const char **pgnames) { + const char *name = "pinctrl-single,pins"; struct pcs_func_vals *vals; - const __be32 *mux; - int size, rows, *pins, index = 0, found = 0, res = -ENOMEM; + int rows, *pins, found = 0, res = -ENOMEM, i; struct pcs_function *function; - mux = of_get_property(np, PCS_MUX_PINS_NAME, &size); - if ((!mux) || (size < sizeof(*mux) * 2)) { - dev_err(pcs->dev, "bad data for mux %s\n", - np->name); + rows = pinctrl_count_index_with_args(np, name); + if (rows <= 0) { + dev_err(pcs->dev, "Ivalid number of rows: %d\n", rows); return -EINVAL; } - size /= sizeof(*mux); /* Number of elements in array */ - rows = size / 2; - vals = devm_kzalloc(pcs->dev, sizeof(*vals) * rows, GFP_KERNEL); if (!vals) return -ENOMEM; @@ -1169,14 +1146,28 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs, if (!pins) goto free_vals; - while (index < size) { - unsigned offset, val; + for (i = 0; i < rows; i++) { + struct of_phandle_args pinctrl_spec; + unsigned int offset; int pin; - offset = be32_to_cpup(mux + index++); - val = be32_to_cpup(mux + index++); + res = pinctrl_parse_index_with_args(np, name, i, &pinctrl_spec); + if (res) + return res; + + if (pinctrl_spec.args_count < 2) { + dev_err(pcs->dev, "invalid args_count for spec: %i\n", + pinctrl_spec.args_count); + break; + } + + /* Index plus one value cell */ + offset = pinctrl_spec.args[0]; vals[found].reg = pcs->base + offset; - vals[found].val = val; + vals[found].val = pinctrl_spec.args[1]; + + dev_dbg(pcs->dev, "%s index: 0x%x value: 0x%x\n", + pinctrl_spec.np->name, offset, pinctrl_spec.args[1]); pin = pcs_get_pin_by_offset(pcs, offset); if (pin < 0) { @@ -1190,8 +1181,10 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs, pgnames[0] = np->name; function = pcs_add_function(pcs, np, np->name, vals, found, pgnames, 1); - if (!function) + if (!function) { + res = -ENOMEM; goto free_pins; + } res = pcs_add_pingroup(pcs, np, np->name, pins, found); if (res < 0) @@ -1226,36 +1219,24 @@ free_vals: return res; } -#define PARAMS_FOR_BITS_PER_MUX 3 - static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs, struct device_node *np, struct pinctrl_map **map, unsigned *num_maps, const char **pgnames) { + const char *name = "pinctrl-single,bits"; struct pcs_func_vals *vals; - const __be32 *mux; - int size, rows, *pins, index = 0, found = 0, res = -ENOMEM; + int rows, *pins, found = 0, res = -ENOMEM, i; int npins_in_row; struct pcs_function *function; - mux = of_get_property(np, PCS_MUX_BITS_NAME, &size); - - if (!mux) { - dev_err(pcs->dev, "no valid property for %s\n", np->name); - return -EINVAL; - } - - if (size < (sizeof(*mux) * PARAMS_FOR_BITS_PER_MUX)) { - dev_err(pcs->dev, "bad data for %s\n", np->name); + rows = pinctrl_count_index_with_args(np, name); + if (rows <= 0) { + dev_err(pcs->dev, "Invalid number of rows: %d\n", rows); return -EINVAL; } - /* Number of elements in array */ - size /= sizeof(*mux); - - rows = size / PARAMS_FOR_BITS_PER_MUX; npins_in_row = pcs->width / pcs->bits_per_pin; vals = devm_kzalloc(pcs->dev, sizeof(*vals) * rows * npins_in_row, @@ -1268,15 +1249,30 @@ static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs, if (!pins) goto free_vals; - while (index < size) { + for (i = 0; i < rows; i++) { + struct of_phandle_args pinctrl_spec; unsigned offset, val; unsigned mask, bit_pos, val_pos, mask_pos, submask; unsigned pin_num_from_lsb; int pin; - offset = be32_to_cpup(mux + index++); - val = be32_to_cpup(mux + index++); - mask = be32_to_cpup(mux + index++); + res = pinctrl_parse_index_with_args(np, name, i, &pinctrl_spec); + if (res) + return res; + + if (pinctrl_spec.args_count < 3) { + dev_err(pcs->dev, "invalid args_count for spec: %i\n", + pinctrl_spec.args_count); + break; + } + + /* Index plus two value cells */ + offset = pinctrl_spec.args[0]; + val = pinctrl_spec.args[1]; + mask = pinctrl_spec.args[2]; + + dev_dbg(pcs->dev, "%s index: 0x%x value: 0x%x mask: 0x%x\n", + pinctrl_spec.np->name, offset, val, mask); /* Parse pins in each row from LSB */ while (mask) { @@ -1319,8 +1315,10 @@ static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs, pgnames[0] = np->name; function = pcs_add_function(pcs, np, np->name, vals, found, pgnames, 1); - if (!function) + if (!function) { + res = -ENOMEM; goto free_pins; + } res = pcs_add_pingroup(pcs, np, np->name, pins, found); if (res < 0) @@ -1494,17 +1492,12 @@ static void pcs_free_resources(struct pcs_device *pcs) pinctrl_unregister(pcs->pctl); pcs_free_funcs(pcs); pcs_free_pingroups(pcs); +#if IS_BUILTIN(CONFIG_PINCTRL_SINGLE) + if (pcs->missing_nr_pinctrl_cells) + of_remove_property(pcs->np, pcs->missing_nr_pinctrl_cells); +#endif } -#define PCS_GET_PROP_U32(name, reg, err) \ - do { \ - ret = of_property_read_u32(np, name, reg); \ - if (ret) { \ - dev_err(pcs->dev, err); \ - return ret; \ - } \ - } while (0); - static const struct of_device_id pcs_of_match[]; static int pcs_add_gpio_func(struct device_node *node, struct pcs_device *pcs) @@ -1820,6 +1813,55 @@ static int pinctrl_single_resume(struct platform_device *pdev) } #endif +/** + * pcs_quirk_missing_pinctrl_cells - handle legacy binding + * @pcs: pinctrl driver instance + * @np: device tree node + * @cells: number of cells + * + * Handle legacy binding with no #pinctrl-cells. This should be + * always two pinctrl-single,bit-per-mux and one for others. + * At some point we may want to consider removing this. + */ +static int pcs_quirk_missing_pinctrl_cells(struct pcs_device *pcs, + struct device_node *np, + int cells) +{ + struct property *p; + const char *name = "#pinctrl-cells"; + int error; + u32 val; + + error = of_property_read_u32(np, name, &val); + if (!error) + return 0; + + dev_warn(pcs->dev, "please update dts to use %s = <%i>\n", + name, cells); + + p = devm_kzalloc(pcs->dev, sizeof(*p), GFP_KERNEL); + if (!p) + return -ENOMEM; + + p->length = sizeof(__be32); + p->value = devm_kzalloc(pcs->dev, sizeof(__be32), GFP_KERNEL); + if (!p->value) + return -ENOMEM; + *(__be32 *)p->value = cpu_to_be32(cells); + + p->name = devm_kstrdup(pcs->dev, name, GFP_KERNEL); + if (!p->name) + return -ENOMEM; + + pcs->missing_nr_pinctrl_cells = p; + +#if IS_BUILTIN(CONFIG_PINCTRL_SINGLE) + error = of_add_property(np, pcs->missing_nr_pinctrl_cells); +#endif + + return error; +} + static int pcs_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -1840,6 +1882,7 @@ static int pcs_probe(struct platform_device *pdev) return -ENOMEM; } pcs->dev = &pdev->dev; + pcs->np = np; raw_spin_lock_init(&pcs->lock); mutex_init(&pcs->mutex); INIT_LIST_HEAD(&pcs->pingroups); @@ -1849,8 +1892,13 @@ static int pcs_probe(struct platform_device *pdev) pcs->flags = soc->flags; memcpy(&pcs->socdata, soc, sizeof(*soc)); - PCS_GET_PROP_U32("pinctrl-single,register-width", &pcs->width, - "register width not specified\n"); + ret = of_property_read_u32(np, "pinctrl-single,register-width", + &pcs->width); + if (ret) { + dev_err(pcs->dev, "register width not specified\n"); + + return ret; + } ret = of_property_read_u32(np, "pinctrl-single,function-mask", &pcs->fmask); @@ -1871,6 +1919,13 @@ static int pcs_probe(struct platform_device *pdev) pcs->bits_per_mux = of_property_read_bool(np, "pinctrl-single,bit-per-mux"); + ret = pcs_quirk_missing_pinctrl_cells(pcs, np, + pcs->bits_per_mux ? 2 : 1); + if (ret) { + dev_err(&pdev->dev, "unable to patch #pinctrl-cells\n"); + + return ret; + } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c index b7bb37167969..676efcc032d2 100644 --- a/drivers/pinctrl/pinctrl-st.c +++ b/drivers/pinctrl/pinctrl-st.c @@ -1006,7 +1006,7 @@ static void st_pinconf_dbg_show(struct pinctrl_dev *pctldev, function = st_pctl_get_pin_function(pc, offset); if (function) - snprintf(f, 10, "Alt Fn %d", function); + snprintf(f, 10, "Alt Fn %u", function); else snprintf(f, 5, "GPIO"); @@ -1181,7 +1181,7 @@ static int st_pctl_dt_parse_groups(struct device_node *np, if (!strcmp(pp->name, "name")) continue; - if (pp && (pp->length/sizeof(__be32)) >= OF_GPIO_ARGS_MIN) { + if (pp->length / sizeof(__be32) >= OF_GPIO_ARGS_MIN) { npins++; } else { pr_warn("Invalid st,pins in %s node\n", np->name); diff --git a/drivers/pinctrl/pinctrl-sx150x.c b/drivers/pinctrl/pinctrl-sx150x.c index d2d4211e615e..29fb7403d24e 100644 --- a/drivers/pinctrl/pinctrl-sx150x.c +++ b/drivers/pinctrl/pinctrl-sx150x.c @@ -5,6 +5,7 @@ * Copyright (c) 2010, Code Aurora Forum. All rights reserved. * * Driver for Semtech SX150X I2C GPIO Expanders + * The handling of the 4-bit chips (SX1501/SX1504/SX1507) is untested. * * Author: Gregory Bean <gbean@codeaurora.org> * @@ -18,6 +19,7 @@ * GNU General Public License for more details. */ +#include <linux/regmap.h> #include <linux/i2c.h> #include <linux/init.h> #include <linux/interrupt.h> @@ -25,8 +27,8 @@ #include <linux/mutex.h> #include <linux/slab.h> #include <linux/of.h> -#include <linux/gpio.h> -#include <linux/pinctrl/machine.h> +#include <linux/of_device.h> +#include <linux/gpio/driver.h> #include <linux/pinctrl/pinconf.h> #include <linux/pinctrl/pinctrl.h> #include <linux/pinctrl/pinmux.h> @@ -42,6 +44,14 @@ enum { SX150X_456, SX150X_789, }; +enum { + SX150X_789_REG_MISC_AUTOCLEAR_OFF = 1 << 0, + SX150X_MAX_REGISTER = 0xad, + SX150X_IRQ_TYPE_EDGE_RISING = 0x1, + SX150X_IRQ_TYPE_EDGE_FALLING = 0x2, + SX150X_789_RESET_KEY1 = 0x12, + SX150X_789_RESET_KEY2 = 0x34, +}; struct sx150x_123_pri { u8 reg_pld_mode; @@ -50,7 +60,7 @@ struct sx150x_123_pri { u8 reg_pld_table2; u8 reg_pld_table3; u8 reg_pld_table4; - u8 reg_advance; + u8 reg_advanced; }; struct sx150x_456_pri { @@ -60,7 +70,7 @@ struct sx150x_456_pri { u8 reg_pld_table2; u8 reg_pld_table3; u8 reg_pld_table4; - u8 reg_advance; + u8 reg_advanced; }; struct sx150x_789_pri { @@ -98,17 +108,23 @@ struct sx150x_pinctrl { struct pinctrl_desc pinctrl_desc; struct gpio_chip gpio; struct irq_chip irq_chip; + struct regmap *regmap; struct { - int update; u32 sense; u32 masked; - u32 dev_sense; - u32 dev_masked; } irq; struct mutex lock; const struct sx150x_device_data *data; }; +static const struct pinctrl_pin_desc sx150x_4_pins[] = { + PINCTRL_PIN(0, "gpio0"), + PINCTRL_PIN(1, "gpio1"), + PINCTRL_PIN(2, "gpio2"), + PINCTRL_PIN(3, "gpio3"), + PINCTRL_PIN(4, "oscio"), +}; + static const struct pinctrl_pin_desc sx150x_8_pins[] = { PINCTRL_PIN(0, "gpio0"), PINCTRL_PIN(1, "gpio1"), @@ -141,179 +157,198 @@ static const struct pinctrl_pin_desc sx150x_16_pins[] = { PINCTRL_PIN(16, "oscio"), }; -static const struct sx150x_device_data sx1508q_device_data = { - .model = SX150X_789, - .reg_pullup = 0x03, - .reg_pulldn = 0x04, - .reg_dir = 0x07, - .reg_data = 0x08, - .reg_irq_mask = 0x09, - .reg_irq_src = 0x0c, - .reg_sense = 0x0b, - .pri.x789 = { - .reg_drain = 0x05, - .reg_polarity = 0x06, - .reg_clock = 0x0f, - .reg_misc = 0x10, - .reg_reset = 0x7d, +static const struct sx150x_device_data sx1501q_device_data = { + .model = SX150X_123, + .reg_pullup = 0x02, + .reg_pulldn = 0x03, + .reg_dir = 0x01, + .reg_data = 0x00, + .reg_irq_mask = 0x05, + .reg_irq_src = 0x08, + .reg_sense = 0x07, + .pri.x123 = { + .reg_pld_mode = 0x10, + .reg_pld_table0 = 0x11, + .reg_pld_table2 = 0x13, + .reg_advanced = 0xad, }, - .ngpios = 8, + .ngpios = 4, + .pins = sx150x_4_pins, + .npins = 4, /* oscio not available */ +}; + +static const struct sx150x_device_data sx1502q_device_data = { + .model = SX150X_123, + .reg_pullup = 0x02, + .reg_pulldn = 0x03, + .reg_dir = 0x01, + .reg_data = 0x00, + .reg_irq_mask = 0x05, + .reg_irq_src = 0x08, + .reg_sense = 0x06, + .pri.x123 = { + .reg_pld_mode = 0x10, + .reg_pld_table0 = 0x11, + .reg_pld_table1 = 0x12, + .reg_pld_table2 = 0x13, + .reg_pld_table3 = 0x14, + .reg_pld_table4 = 0x15, + .reg_advanced = 0xad, + }, + .ngpios = 8, .pins = sx150x_8_pins, - .npins = ARRAY_SIZE(sx150x_8_pins), + .npins = 8, /* oscio not available */ }; -static const struct sx150x_device_data sx1509q_device_data = { - .model = SX150X_789, - .reg_pullup = 0x07, - .reg_pulldn = 0x09, - .reg_dir = 0x0f, - .reg_data = 0x11, - .reg_irq_mask = 0x13, - .reg_irq_src = 0x19, - .reg_sense = 0x17, - .pri.x789 = { - .reg_drain = 0x0b, - .reg_polarity = 0x0d, - .reg_clock = 0x1e, - .reg_misc = 0x1f, - .reg_reset = 0x7d, +static const struct sx150x_device_data sx1503q_device_data = { + .model = SX150X_123, + .reg_pullup = 0x04, + .reg_pulldn = 0x06, + .reg_dir = 0x02, + .reg_data = 0x00, + .reg_irq_mask = 0x08, + .reg_irq_src = 0x0e, + .reg_sense = 0x0a, + .pri.x123 = { + .reg_pld_mode = 0x20, + .reg_pld_table0 = 0x22, + .reg_pld_table1 = 0x24, + .reg_pld_table2 = 0x26, + .reg_pld_table3 = 0x28, + .reg_pld_table4 = 0x2a, + .reg_advanced = 0xad, }, .ngpios = 16, .pins = sx150x_16_pins, - .npins = ARRAY_SIZE(sx150x_16_pins), + .npins = 16, /* oscio not available */ }; -static const struct sx150x_device_data sx1506q_device_data = { +static const struct sx150x_device_data sx1504q_device_data = { .model = SX150X_456, - .reg_pullup = 0x05, - .reg_pulldn = 0x07, - .reg_dir = 0x03, - .reg_data = 0x01, - .reg_irq_mask = 0x09, - .reg_irq_src = 0x0f, - .reg_sense = 0x0d, + .reg_pullup = 0x02, + .reg_pulldn = 0x03, + .reg_dir = 0x01, + .reg_data = 0x00, + .reg_irq_mask = 0x05, + .reg_irq_src = 0x08, + .reg_sense = 0x07, .pri.x456 = { - .reg_pld_mode = 0x21, - .reg_pld_table0 = 0x23, - .reg_pld_table1 = 0x25, - .reg_pld_table2 = 0x27, - .reg_pld_table3 = 0x29, - .reg_pld_table4 = 0x2b, - .reg_advance = 0xad, + .reg_pld_mode = 0x10, + .reg_pld_table0 = 0x11, + .reg_pld_table2 = 0x13, }, - .ngpios = 16, - .pins = sx150x_16_pins, - .npins = 16, /* oscio not available */ + .ngpios = 4, + .pins = sx150x_4_pins, + .npins = 4, /* oscio not available */ }; -static const struct sx150x_device_data sx1502q_device_data = { - .model = SX150X_123, +static const struct sx150x_device_data sx1505q_device_data = { + .model = SX150X_456, .reg_pullup = 0x02, .reg_pulldn = 0x03, .reg_dir = 0x01, .reg_data = 0x00, .reg_irq_mask = 0x05, .reg_irq_src = 0x08, - .reg_sense = 0x07, - .pri.x123 = { + .reg_sense = 0x06, + .pri.x456 = { .reg_pld_mode = 0x10, .reg_pld_table0 = 0x11, .reg_pld_table1 = 0x12, .reg_pld_table2 = 0x13, .reg_pld_table3 = 0x14, .reg_pld_table4 = 0x15, - .reg_advance = 0xad, }, .ngpios = 8, .pins = sx150x_8_pins, .npins = 8, /* oscio not available */ }; -static s32 sx150x_i2c_write(struct i2c_client *client, u8 reg, u8 val) -{ - s32 err = i2c_smbus_write_byte_data(client, reg, val); - - if (err < 0) - dev_warn(&client->dev, - "i2c write fail: can't write %02x to %02x: %d\n", - val, reg, err); - return err; -} - -static s32 sx150x_i2c_read(struct i2c_client *client, u8 reg, u8 *val) -{ - s32 err = i2c_smbus_read_byte_data(client, reg); - - if (err >= 0) - *val = err; - else - dev_warn(&client->dev, - "i2c read fail: can't read from %02x: %d\n", - reg, err); - return err; -} - -/* - * These utility functions solve the common problem of locating and setting - * configuration bits. Configuration bits are grouped into registers - * whose indexes increase downwards. For example, with eight-bit registers, - * sixteen gpios would have their config bits grouped in the following order: - * REGISTER N-1 [ f e d c b a 9 8 ] - * N [ 7 6 5 4 3 2 1 0 ] - * - * For multi-bit configurations, the pattern gets wider: - * REGISTER N-3 [ f f e e d d c c ] - * N-2 [ b b a a 9 9 8 8 ] - * N-1 [ 7 7 6 6 5 5 4 4 ] - * N [ 3 3 2 2 1 1 0 0 ] - * - * Given the address of the starting register 'N', the index of the gpio - * whose configuration we seek to change, and the width in bits of that - * configuration, these functions allow us to locate the correct - * register and mask the correct bits. - */ -static inline void sx150x_find_cfg(u8 offset, u8 width, - u8 *reg, u8 *mask, u8 *shift) -{ - *reg -= offset * width / 8; - *mask = (1 << width) - 1; - *shift = (offset * width) % 8; - *mask <<= *shift; -} - -static int sx150x_write_cfg(struct i2c_client *client, - u8 offset, u8 width, u8 reg, u8 val) -{ - u8 mask; - u8 data; - u8 shift; - int err; - - sx150x_find_cfg(offset, width, ®, &mask, &shift); - err = sx150x_i2c_read(client, reg, &data); - if (err < 0) - return err; - - data &= ~mask; - data |= (val << shift) & mask; - return sx150x_i2c_write(client, reg, data); -} +static const struct sx150x_device_data sx1506q_device_data = { + .model = SX150X_456, + .reg_pullup = 0x04, + .reg_pulldn = 0x06, + .reg_dir = 0x02, + .reg_data = 0x00, + .reg_irq_mask = 0x08, + .reg_irq_src = 0x0e, + .reg_sense = 0x0a, + .pri.x456 = { + .reg_pld_mode = 0x20, + .reg_pld_table0 = 0x22, + .reg_pld_table1 = 0x24, + .reg_pld_table2 = 0x26, + .reg_pld_table3 = 0x28, + .reg_pld_table4 = 0x2a, + .reg_advanced = 0xad, + }, + .ngpios = 16, + .pins = sx150x_16_pins, + .npins = 16, /* oscio not available */ +}; -static int sx150x_read_cfg(struct i2c_client *client, - u8 offset, u8 width, u8 reg) -{ - u8 mask; - u8 data; - u8 shift; - int err; +static const struct sx150x_device_data sx1507q_device_data = { + .model = SX150X_789, + .reg_pullup = 0x03, + .reg_pulldn = 0x04, + .reg_dir = 0x07, + .reg_data = 0x08, + .reg_irq_mask = 0x09, + .reg_irq_src = 0x0b, + .reg_sense = 0x0a, + .pri.x789 = { + .reg_drain = 0x05, + .reg_polarity = 0x06, + .reg_clock = 0x0d, + .reg_misc = 0x0e, + .reg_reset = 0x7d, + }, + .ngpios = 4, + .pins = sx150x_4_pins, + .npins = ARRAY_SIZE(sx150x_4_pins), +}; - sx150x_find_cfg(offset, width, ®, &mask, &shift); - err = sx150x_i2c_read(client, reg, &data); - if (err < 0) - return err; +static const struct sx150x_device_data sx1508q_device_data = { + .model = SX150X_789, + .reg_pullup = 0x03, + .reg_pulldn = 0x04, + .reg_dir = 0x07, + .reg_data = 0x08, + .reg_irq_mask = 0x09, + .reg_irq_src = 0x0c, + .reg_sense = 0x0a, + .pri.x789 = { + .reg_drain = 0x05, + .reg_polarity = 0x06, + .reg_clock = 0x0f, + .reg_misc = 0x10, + .reg_reset = 0x7d, + }, + .ngpios = 8, + .pins = sx150x_8_pins, + .npins = ARRAY_SIZE(sx150x_8_pins), +}; - return (data & mask); -} +static const struct sx150x_device_data sx1509q_device_data = { + .model = SX150X_789, + .reg_pullup = 0x06, + .reg_pulldn = 0x08, + .reg_dir = 0x0e, + .reg_data = 0x10, + .reg_irq_mask = 0x12, + .reg_irq_src = 0x18, + .reg_sense = 0x14, + .pri.x789 = { + .reg_drain = 0x0a, + .reg_polarity = 0x0c, + .reg_clock = 0x1e, + .reg_misc = 0x1f, + .reg_reset = 0x7d, + }, + .ngpios = 16, + .pins = sx150x_16_pins, + .npins = ARRAY_SIZE(sx150x_16_pins), +}; static int sx150x_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) { @@ -360,31 +395,33 @@ static int sx150x_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) { struct sx150x_pinctrl *pctl = gpiochip_get_data(chip); - int status; + unsigned int value; + int ret; if (sx150x_pin_is_oscio(pctl, offset)) return false; - status = sx150x_read_cfg(pctl->client, offset, 1, pctl->data->reg_dir); - if (status >= 0) - status = !!status; + ret = regmap_read(pctl->regmap, pctl->data->reg_dir, &value); + if (ret < 0) + return ret; - return status; + return !!(value & BIT(offset)); } static int sx150x_gpio_get(struct gpio_chip *chip, unsigned int offset) { struct sx150x_pinctrl *pctl = gpiochip_get_data(chip); - int status; + unsigned int value; + int ret; if (sx150x_pin_is_oscio(pctl, offset)) return -EINVAL; - status = sx150x_read_cfg(pctl->client, offset, 1, pctl->data->reg_data); - if (status >= 0) - status = !!status; + ret = regmap_read(pctl->regmap, pctl->data->reg_data, &value); + if (ret < 0) + return ret; - return status; + return !!(value & BIT(offset)); } static int sx150x_gpio_set_single_ended(struct gpio_chip *chip, @@ -400,13 +437,9 @@ static int sx150x_gpio_set_single_ended(struct gpio_chip *chip, sx150x_pin_is_oscio(pctl, offset)) return 0; - mutex_lock(&pctl->lock); - ret = sx150x_write_cfg(pctl->client, offset, 1, - pctl->data->pri.x789.reg_drain, - 0); - mutex_unlock(&pctl->lock); - if (ret < 0) - return ret; + ret = regmap_write_bits(pctl->regmap, + pctl->data->pri.x789.reg_drain, + BIT(offset), 0); break; case LINE_MODE_OPEN_DRAIN: @@ -414,81 +447,83 @@ static int sx150x_gpio_set_single_ended(struct gpio_chip *chip, sx150x_pin_is_oscio(pctl, offset)) return -ENOTSUPP; - mutex_lock(&pctl->lock); - ret = sx150x_write_cfg(pctl->client, offset, 1, - pctl->data->pri.x789.reg_drain, - 1); - mutex_unlock(&pctl->lock); - if (ret < 0) - return ret; + ret = regmap_write_bits(pctl->regmap, + pctl->data->pri.x789.reg_drain, + BIT(offset), BIT(offset)); break; - default: - return -ENOTSUPP; + ret = -ENOTSUPP; + break; } - return 0; + return ret; +} + +static int __sx150x_gpio_set(struct sx150x_pinctrl *pctl, unsigned int offset, + int value) +{ + return regmap_write_bits(pctl->regmap, pctl->data->reg_data, + BIT(offset), value ? BIT(offset) : 0); +} + +static int sx150x_gpio_oscio_set(struct sx150x_pinctrl *pctl, + int value) +{ + return regmap_write(pctl->regmap, + pctl->data->pri.x789.reg_clock, + (value ? 0x1f : 0x10)); } static void sx150x_gpio_set(struct gpio_chip *chip, unsigned int offset, - int value) + int value) { struct sx150x_pinctrl *pctl = gpiochip_get_data(chip); - if (sx150x_pin_is_oscio(pctl, offset)) { + if (sx150x_pin_is_oscio(pctl, offset)) + sx150x_gpio_oscio_set(pctl, value); + else + __sx150x_gpio_set(pctl, offset, value); - mutex_lock(&pctl->lock); - sx150x_i2c_write(pctl->client, - pctl->data->pri.x789.reg_clock, - (value ? 0x1f : 0x10)); - mutex_unlock(&pctl->lock); - } else { - mutex_lock(&pctl->lock); - sx150x_write_cfg(pctl->client, offset, 1, - pctl->data->reg_data, - (value ? 1 : 0)); - mutex_unlock(&pctl->lock); - } +} + +static void sx150x_gpio_set_multiple(struct gpio_chip *chip, + unsigned long *mask, + unsigned long *bits) +{ + struct sx150x_pinctrl *pctl = gpiochip_get_data(chip); + + regmap_write_bits(pctl->regmap, pctl->data->reg_data, *mask, *bits); } static int sx150x_gpio_direction_input(struct gpio_chip *chip, - unsigned int offset) + unsigned int offset) { struct sx150x_pinctrl *pctl = gpiochip_get_data(chip); - int ret; if (sx150x_pin_is_oscio(pctl, offset)) return -EINVAL; - mutex_lock(&pctl->lock); - ret = sx150x_write_cfg(pctl->client, offset, 1, - pctl->data->reg_dir, 1); - mutex_unlock(&pctl->lock); - - return ret; + return regmap_write_bits(pctl->regmap, + pctl->data->reg_dir, + BIT(offset), BIT(offset)); } static int sx150x_gpio_direction_output(struct gpio_chip *chip, - unsigned int offset, int value) + unsigned int offset, int value) { struct sx150x_pinctrl *pctl = gpiochip_get_data(chip); - int status; + int ret; - if (sx150x_pin_is_oscio(pctl, offset)) { - sx150x_gpio_set(chip, offset, value); - return 0; - } + if (sx150x_pin_is_oscio(pctl, offset)) + return sx150x_gpio_oscio_set(pctl, value); - mutex_lock(&pctl->lock); - status = sx150x_write_cfg(pctl->client, offset, 1, - pctl->data->reg_data, - (value ? 1 : 0)); - if (status >= 0) - status = sx150x_write_cfg(pctl->client, offset, 1, - pctl->data->reg_dir, 0); - mutex_unlock(&pctl->lock); + ret = __sx150x_gpio_set(pctl, offset, value); + if (ret < 0) + return ret; - return status; + return regmap_write_bits(pctl->regmap, + pctl->data->reg_dir, + BIT(offset), 0); } static void sx150x_irq_mask(struct irq_data *d) @@ -497,8 +532,7 @@ static void sx150x_irq_mask(struct irq_data *d) gpiochip_get_data(irq_data_get_irq_chip_data(d)); unsigned int n = d->hwirq; - pctl->irq.masked |= (1 << n); - pctl->irq.update = n; + pctl->irq.masked |= BIT(n); } static void sx150x_irq_unmask(struct irq_data *d) @@ -507,8 +541,22 @@ static void sx150x_irq_unmask(struct irq_data *d) gpiochip_get_data(irq_data_get_irq_chip_data(d)); unsigned int n = d->hwirq; - pctl->irq.masked &= ~(1 << n); - pctl->irq.update = n; + pctl->irq.masked &= ~BIT(n); +} + +static void sx150x_irq_set_sense(struct sx150x_pinctrl *pctl, + unsigned int line, unsigned int sense) +{ + /* + * Every interrupt line is represented by two bits shifted + * proportionally to the line number + */ + const unsigned int n = line * 2; + const unsigned int mask = ~((SX150X_IRQ_TYPE_EDGE_RISING | + SX150X_IRQ_TYPE_EDGE_FALLING) << n); + + pctl->irq.sense &= mask; + pctl->irq.sense |= sense << n; } static int sx150x_irq_set_type(struct irq_data *d, unsigned int flow_type) @@ -523,51 +571,34 @@ static int sx150x_irq_set_type(struct irq_data *d, unsigned int flow_type) n = d->hwirq; if (flow_type & IRQ_TYPE_EDGE_RISING) - val |= 0x1; + val |= SX150X_IRQ_TYPE_EDGE_RISING; if (flow_type & IRQ_TYPE_EDGE_FALLING) - val |= 0x2; + val |= SX150X_IRQ_TYPE_EDGE_FALLING; - pctl->irq.sense &= ~(3UL << (n * 2)); - pctl->irq.sense |= val << (n * 2); - pctl->irq.update = n; + sx150x_irq_set_sense(pctl, n, val); return 0; } static irqreturn_t sx150x_irq_thread_fn(int irq, void *dev_id) { struct sx150x_pinctrl *pctl = (struct sx150x_pinctrl *)dev_id; - unsigned int nhandled = 0; - unsigned int sub_irq; - unsigned int n; - s32 err; - u8 val; - int i; + unsigned long n, status; + unsigned int val; + int err; - for (i = (pctl->data->ngpios / 8) - 1; i >= 0; --i) { - err = sx150x_i2c_read(pctl->client, - pctl->data->reg_irq_src - i, - &val); - if (err < 0) - continue; + err = regmap_read(pctl->regmap, pctl->data->reg_irq_src, &val); + if (err < 0) + return IRQ_NONE; - err = sx150x_i2c_write(pctl->client, - pctl->data->reg_irq_src - i, - val); - if (err < 0) - continue; - - for (n = 0; n < 8; ++n) { - if (val & (1 << n)) { - sub_irq = irq_find_mapping( - pctl->gpio.irqdomain, - (i * 8) + n); - handle_nested_irq(sub_irq); - ++nhandled; - } - } - } + err = regmap_write(pctl->regmap, pctl->data->reg_irq_src, val); + if (err < 0) + return IRQ_NONE; - return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE); + status = val; + for_each_set_bit(n, &status, pctl->data->ngpios) + handle_nested_irq(irq_find_mapping(pctl->gpio.irqdomain, n)); + + return IRQ_HANDLED; } static void sx150x_irq_bus_lock(struct irq_data *d) @@ -582,35 +613,9 @@ static void sx150x_irq_bus_sync_unlock(struct irq_data *d) { struct sx150x_pinctrl *pctl = gpiochip_get_data(irq_data_get_irq_chip_data(d)); - unsigned int n; - - if (pctl->irq.update < 0) - goto out; - n = pctl->irq.update; - pctl->irq.update = -1; - - /* Avoid updates if nothing changed */ - if (pctl->irq.dev_sense == pctl->irq.sense && - pctl->irq.dev_masked == pctl->irq.masked) - goto out; - - pctl->irq.dev_sense = pctl->irq.sense; - pctl->irq.dev_masked = pctl->irq.masked; - - if (pctl->irq.masked & (1 << n)) { - sx150x_write_cfg(pctl->client, n, 1, - pctl->data->reg_irq_mask, 1); - sx150x_write_cfg(pctl->client, n, 2, - pctl->data->reg_sense, 0); - } else { - sx150x_write_cfg(pctl->client, n, 1, - pctl->data->reg_irq_mask, 0); - sx150x_write_cfg(pctl->client, n, 2, - pctl->data->reg_sense, - pctl->irq.sense >> (n * 2)); - } -out: + regmap_write(pctl->regmap, pctl->data->reg_irq_mask, pctl->irq.masked); + regmap_write(pctl->regmap, pctl->data->reg_sense, pctl->irq.sense); mutex_unlock(&pctl->lock); } @@ -621,19 +626,15 @@ static int sx150x_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, unsigned int param = pinconf_to_config_param(*config); int ret; u32 arg; + unsigned int data; if (sx150x_pin_is_oscio(pctl, pin)) { - u8 data; - switch (param) { case PIN_CONFIG_DRIVE_PUSH_PULL: case PIN_CONFIG_OUTPUT: - mutex_lock(&pctl->lock); - ret = sx150x_i2c_read(pctl->client, - pctl->data->pri.x789.reg_clock, - &data); - mutex_unlock(&pctl->lock); - + ret = regmap_read(pctl->regmap, + pctl->data->pri.x789.reg_clock, + &data); if (ret < 0) return ret; @@ -658,10 +659,10 @@ static int sx150x_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, switch (param) { case PIN_CONFIG_BIAS_PULL_DOWN: - mutex_lock(&pctl->lock); - ret = sx150x_read_cfg(pctl->client, pin, 1, - pctl->data->reg_pulldn); - mutex_unlock(&pctl->lock); + ret = regmap_read(pctl->regmap, + pctl->data->reg_pulldn, + &data); + data &= BIT(pin); if (ret < 0) return ret; @@ -673,10 +674,10 @@ static int sx150x_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, break; case PIN_CONFIG_BIAS_PULL_UP: - mutex_lock(&pctl->lock); - ret = sx150x_read_cfg(pctl->client, pin, 1, - pctl->data->reg_pullup); - mutex_unlock(&pctl->lock); + ret = regmap_read(pctl->regmap, + pctl->data->reg_pullup, + &data); + data &= BIT(pin); if (ret < 0) return ret; @@ -691,15 +692,15 @@ static int sx150x_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, if (pctl->data->model != SX150X_789) return -ENOTSUPP; - mutex_lock(&pctl->lock); - ret = sx150x_read_cfg(pctl->client, pin, 1, - pctl->data->pri.x789.reg_drain); - mutex_unlock(&pctl->lock); + ret = regmap_read(pctl->regmap, + pctl->data->pri.x789.reg_drain, + &data); + data &= BIT(pin); if (ret < 0) return ret; - if (!ret) + if (!data) return -EINVAL; arg = 1; @@ -709,15 +710,15 @@ static int sx150x_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, if (pctl->data->model != SX150X_789) arg = true; else { - mutex_lock(&pctl->lock); - ret = sx150x_read_cfg(pctl->client, pin, 1, - pctl->data->pri.x789.reg_drain); - mutex_unlock(&pctl->lock); + ret = regmap_read(pctl->regmap, + pctl->data->pri.x789.reg_drain, + &data); + data &= BIT(pin); if (ret < 0) return ret; - if (ret) + if (data) return -EINVAL; arg = 1; @@ -777,39 +778,33 @@ static int sx150x_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, switch (param) { case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: case PIN_CONFIG_BIAS_DISABLE: - mutex_lock(&pctl->lock); - ret = sx150x_write_cfg(pctl->client, pin, 1, - pctl->data->reg_pulldn, 0); - mutex_unlock(&pctl->lock); + ret = regmap_write_bits(pctl->regmap, + pctl->data->reg_pulldn, + BIT(pin), 0); if (ret < 0) return ret; - mutex_lock(&pctl->lock); - ret = sx150x_write_cfg(pctl->client, pin, 1, - pctl->data->reg_pullup, 0); - mutex_unlock(&pctl->lock); + ret = regmap_write_bits(pctl->regmap, + pctl->data->reg_pullup, + BIT(pin), 0); if (ret < 0) return ret; break; case PIN_CONFIG_BIAS_PULL_UP: - mutex_lock(&pctl->lock); - ret = sx150x_write_cfg(pctl->client, pin, 1, - pctl->data->reg_pullup, - 1); - mutex_unlock(&pctl->lock); + ret = regmap_write_bits(pctl->regmap, + pctl->data->reg_pullup, + BIT(pin), BIT(pin)); if (ret < 0) return ret; break; case PIN_CONFIG_BIAS_PULL_DOWN: - mutex_lock(&pctl->lock); - ret = sx150x_write_cfg(pctl->client, pin, 1, - pctl->data->reg_pulldn, - 1); - mutex_unlock(&pctl->lock); + ret = regmap_write_bits(pctl->regmap, + pctl->data->reg_pulldn, + BIT(pin), BIT(pin)); if (ret < 0) return ret; @@ -854,49 +849,86 @@ static const struct pinconf_ops sx150x_pinconf_ops = { }; static const struct i2c_device_id sx150x_id[] = { + {"sx1501q", (kernel_ulong_t) &sx1501q_device_data }, + {"sx1502q", (kernel_ulong_t) &sx1502q_device_data }, + {"sx1503q", (kernel_ulong_t) &sx1503q_device_data }, + {"sx1504q", (kernel_ulong_t) &sx1504q_device_data }, + {"sx1505q", (kernel_ulong_t) &sx1505q_device_data }, + {"sx1506q", (kernel_ulong_t) &sx1506q_device_data }, + {"sx1507q", (kernel_ulong_t) &sx1507q_device_data }, {"sx1508q", (kernel_ulong_t) &sx1508q_device_data }, {"sx1509q", (kernel_ulong_t) &sx1509q_device_data }, - {"sx1506q", (kernel_ulong_t) &sx1506q_device_data }, - {"sx1502q", (kernel_ulong_t) &sx1502q_device_data }, {} }; static const struct of_device_id sx150x_of_match[] = { - { .compatible = "semtech,sx1508q" }, - { .compatible = "semtech,sx1509q" }, - { .compatible = "semtech,sx1506q" }, - { .compatible = "semtech,sx1502q" }, + { .compatible = "semtech,sx1501q", .data = &sx1501q_device_data }, + { .compatible = "semtech,sx1502q", .data = &sx1502q_device_data }, + { .compatible = "semtech,sx1503q", .data = &sx1503q_device_data }, + { .compatible = "semtech,sx1504q", .data = &sx1504q_device_data }, + { .compatible = "semtech,sx1505q", .data = &sx1505q_device_data }, + { .compatible = "semtech,sx1506q", .data = &sx1506q_device_data }, + { .compatible = "semtech,sx1507q", .data = &sx1507q_device_data }, + { .compatible = "semtech,sx1508q", .data = &sx1508q_device_data }, + { .compatible = "semtech,sx1509q", .data = &sx1509q_device_data }, {}, }; -static int sx150x_init_io(struct sx150x_pinctrl *pctl, u8 base, u16 cfg) -{ - int err = 0; - unsigned int n; - - for (n = 0; err >= 0 && n < (pctl->data->ngpios / 8); ++n) - err = sx150x_i2c_write(pctl->client, base - n, cfg >> (n * 8)); - return err; -} - static int sx150x_reset(struct sx150x_pinctrl *pctl) { int err; err = i2c_smbus_write_byte_data(pctl->client, pctl->data->pri.x789.reg_reset, - 0x12); + SX150X_789_RESET_KEY1); if (err < 0) return err; err = i2c_smbus_write_byte_data(pctl->client, pctl->data->pri.x789.reg_reset, - 0x34); + SX150X_789_RESET_KEY2); return err; } +static int sx150x_init_misc(struct sx150x_pinctrl *pctl) +{ + u8 reg, value; + + switch (pctl->data->model) { + case SX150X_789: + reg = pctl->data->pri.x789.reg_misc; + value = SX150X_789_REG_MISC_AUTOCLEAR_OFF; + break; + case SX150X_456: + reg = pctl->data->pri.x456.reg_advanced; + value = 0x00; + + /* + * Only SX1506 has RegAdvanced, SX1504/5 are expected + * to initialize this offset to zero + */ + if (!reg) + return 0; + break; + case SX150X_123: + reg = pctl->data->pri.x123.reg_advanced; + value = 0x00; + break; + default: + WARN(1, "Unknown chip model %d\n", pctl->data->model); + return -EINVAL; + } + + return regmap_write(pctl->regmap, reg, value); +} + static int sx150x_init_hw(struct sx150x_pinctrl *pctl) { + const u8 reg[] = { + [SX150X_789] = pctl->data->pri.x789.reg_polarity, + [SX150X_456] = pctl->data->pri.x456.reg_pld_mode, + [SX150X_123] = pctl->data->pri.x123.reg_pld_mode, + }; int err; if (pctl->data->model == SX150X_789 && @@ -906,47 +938,193 @@ static int sx150x_init_hw(struct sx150x_pinctrl *pctl) return err; } - if (pctl->data->model == SX150X_789) - err = sx150x_i2c_write(pctl->client, - pctl->data->pri.x789.reg_misc, - 0x01); - else if (pctl->data->model == SX150X_456) - err = sx150x_i2c_write(pctl->client, - pctl->data->pri.x456.reg_advance, - 0x04); - else - err = sx150x_i2c_write(pctl->client, - pctl->data->pri.x123.reg_advance, - 0x00); + err = sx150x_init_misc(pctl); if (err < 0) return err; /* Set all pins to work in normal mode */ - if (pctl->data->model == SX150X_789) { - err = sx150x_init_io(pctl, - pctl->data->pri.x789.reg_polarity, - 0); - if (err < 0) - return err; - } else if (pctl->data->model == SX150X_456) { - /* Set all pins to work in normal mode */ - err = sx150x_init_io(pctl, - pctl->data->pri.x456.reg_pld_mode, - 0); - if (err < 0) - return err; + return regmap_write(pctl->regmap, reg[pctl->data->model], 0); +} + +static int sx150x_regmap_reg_width(struct sx150x_pinctrl *pctl, + unsigned int reg) +{ + const struct sx150x_device_data *data = pctl->data; + + if (reg == data->reg_sense) { + /* + * RegSense packs two bits of configuration per GPIO, + * so we'd need to read twice as many bits as there + * are GPIO in our chip + */ + return 2 * data->ngpios; + } else if ((data->model == SX150X_789 && + (reg == data->pri.x789.reg_misc || + reg == data->pri.x789.reg_clock || + reg == data->pri.x789.reg_reset)) + || + (data->model == SX150X_123 && + reg == data->pri.x123.reg_advanced) + || + (data->model == SX150X_456 && + data->pri.x456.reg_advanced && + reg == data->pri.x456.reg_advanced)) { + return 8; } else { - /* Set all pins to work in normal mode */ - err = sx150x_init_io(pctl, - pctl->data->pri.x123.reg_pld_mode, - 0); - if (err < 0) - return err; + return data->ngpios; + } +} + +static unsigned int sx150x_maybe_swizzle(struct sx150x_pinctrl *pctl, + unsigned int reg, unsigned int val) +{ + unsigned int a, b; + const struct sx150x_device_data *data = pctl->data; + + /* + * Whereas SX1509 presents RegSense in a simple layout as such: + * reg [ f f e e d d c c ] + * reg + 1 [ b b a a 9 9 8 8 ] + * reg + 2 [ 7 7 6 6 5 5 4 4 ] + * reg + 3 [ 3 3 2 2 1 1 0 0 ] + * + * SX1503 and SX1506 deviate from that data layout, instead storing + * their contents as follows: + * + * reg [ f f e e d d c c ] + * reg + 1 [ 7 7 6 6 5 5 4 4 ] + * reg + 2 [ b b a a 9 9 8 8 ] + * reg + 3 [ 3 3 2 2 1 1 0 0 ] + * + * so, taking that into account, we swap two + * inner bytes of a 4-byte result + */ + + if (reg == data->reg_sense && + data->ngpios == 16 && + (data->model == SX150X_123 || + data->model == SX150X_456)) { + a = val & 0x00ff0000; + b = val & 0x0000ff00; + + val &= 0xff0000ff; + val |= b << 8; + val |= a >> 8; + } + + return val; +} + +/* + * In order to mask the differences between 16 and 8 bit expander + * devices we set up a sligthly ficticious regmap that pretends to be + * a set of 32-bit (to accomodate RegSenseLow/RegSenseHigh + * pair/quartet) registers and transparently reconstructs those + * registers via multiple I2C/SMBus reads + * + * This way the rest of the driver code, interfacing with the chip via + * regmap API, can work assuming that each GPIO pin is represented by + * a group of bits at an offset proportional to GPIO number within a + * given register. + */ +static int sx150x_regmap_reg_read(void *context, unsigned int reg, + unsigned int *result) +{ + int ret, n; + struct sx150x_pinctrl *pctl = context; + struct i2c_client *i2c = pctl->client; + const int width = sx150x_regmap_reg_width(pctl, reg); + unsigned int idx, val; + + /* + * There are four potential cases covered by this function: + * + * 1) 8-pin chip, single configuration bit register + * + * This is trivial the code below just needs to read: + * reg [ 7 6 5 4 3 2 1 0 ] + * + * 2) 8-pin chip, double configuration bit register (RegSense) + * + * The read will be done as follows: + * reg [ 7 7 6 6 5 5 4 4 ] + * reg + 1 [ 3 3 2 2 1 1 0 0 ] + * + * 3) 16-pin chip, single configuration bit register + * + * The read will be done as follows: + * reg [ f e d c b a 9 8 ] + * reg + 1 [ 7 6 5 4 3 2 1 0 ] + * + * 4) 16-pin chip, double configuration bit register (RegSense) + * + * The read will be done as follows: + * reg [ f f e e d d c c ] + * reg + 1 [ b b a a 9 9 8 8 ] + * reg + 2 [ 7 7 6 6 5 5 4 4 ] + * reg + 3 [ 3 3 2 2 1 1 0 0 ] + */ + + for (n = width, val = 0, idx = reg; n > 0; n -= 8, idx++) { + val <<= 8; + + ret = i2c_smbus_read_byte_data(i2c, idx); + if (ret < 0) + return ret; + + val |= ret; } + *result = sx150x_maybe_swizzle(pctl, reg, val); + + return 0; +} + +static int sx150x_regmap_reg_write(void *context, unsigned int reg, + unsigned int val) +{ + int ret, n; + struct sx150x_pinctrl *pctl = context; + struct i2c_client *i2c = pctl->client; + const int width = sx150x_regmap_reg_width(pctl, reg); + + val = sx150x_maybe_swizzle(pctl, reg, val); + + n = (width - 1) & ~7; + do { + const u8 byte = (val >> n) & 0xff; + + ret = i2c_smbus_write_byte_data(i2c, reg, byte); + if (ret < 0) + return ret; + + reg++; + n -= 8; + } while (n >= 0); + return 0; } +static bool sx150x_reg_volatile(struct device *dev, unsigned int reg) +{ + struct sx150x_pinctrl *pctl = i2c_get_clientdata(to_i2c_client(dev)); + + return reg == pctl->data->reg_irq_src || reg == pctl->data->reg_data; +} + +const struct regmap_config sx150x_regmap_config = { + .reg_bits = 8, + .val_bits = 32, + + .cache_type = REGCACHE_RBTREE, + + .reg_read = sx150x_regmap_reg_read, + .reg_write = sx150x_regmap_reg_write, + + .max_register = SX150X_MAX_REGISTER, + .volatile_reg = sx150x_reg_volatile, +}; + static int sx150x_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -956,9 +1134,6 @@ static int sx150x_probe(struct i2c_client *client, struct sx150x_pinctrl *pctl; int ret; - if (!id->driver_data) - return -EINVAL; - if (!i2c_check_functionality(client->adapter, i2c_funcs)) return -ENOSYS; @@ -966,9 +1141,27 @@ static int sx150x_probe(struct i2c_client *client, if (!pctl) return -ENOMEM; + i2c_set_clientdata(client, pctl); + pctl->dev = dev; pctl->client = client; - pctl->data = (void *)id->driver_data; + + if (dev->of_node) + pctl->data = of_device_get_match_data(dev); + else + pctl->data = (struct sx150x_device_data *)id->driver_data; + + if (!pctl->data) + return -EINVAL; + + pctl->regmap = devm_regmap_init(dev, NULL, pctl, + &sx150x_regmap_config); + if (IS_ERR(pctl->regmap)) { + ret = PTR_ERR(pctl->regmap); + dev_err(dev, "Failed to allocate register map: %d\n", + ret); + return ret; + } mutex_init(&pctl->lock); @@ -991,6 +1184,14 @@ static int sx150x_probe(struct i2c_client *client, pctl->gpio.of_node = dev->of_node; #endif pctl->gpio.can_sleep = true; + /* + * Setting multiple pins is not safe when all pins are not + * handled by the same regmap register. The oscio pin (present + * on the SX150X_789 chips) lives in its own register, so + * would require locking that is not in place at this time. + */ + if (pctl->data->model != SX150X_789) + pctl->gpio.set_multiple = sx150x_gpio_set_multiple; ret = devm_gpiochip_add_data(dev, &pctl->gpio, pctl); if (ret) @@ -1008,13 +1209,21 @@ static int sx150x_probe(struct i2c_client *client, pctl->irq.masked = ~0; pctl->irq.sense = 0; - pctl->irq.dev_masked = ~0; - pctl->irq.dev_sense = 0; - pctl->irq.update = -1; - ret = gpiochip_irqchip_add(&pctl->gpio, - &pctl->irq_chip, 0, - handle_edge_irq, IRQ_TYPE_NONE); + /* + * Because sx150x_irq_threaded_fn invokes all of the + * nested interrrupt handlers via handle_nested_irq, + * any "handler" passed to gpiochip_irqchip_add() + * below is going to be ignored, so the choice of the + * function does not matter that much. + * + * We set it to handle_bad_irq to avoid confusion, + * plus it will be instantly noticeable if it is ever + * called (should not happen) + */ + ret = gpiochip_irqchip_add_nested(&pctl->gpio, + &pctl->irq_chip, 0, + handle_bad_irq, IRQ_TYPE_NONE); if (ret) { dev_err(dev, "could not connect irqchip to gpiochip\n"); return ret; @@ -1027,6 +1236,10 @@ static int sx150x_probe(struct i2c_client *client, pctl->irq_chip.name, pctl); if (ret < 0) return ret; + + gpiochip_set_nested_irqchip(&pctl->gpio, + &pctl->irq_chip, + client->irq); } /* Pinctrl_desc */ diff --git a/drivers/pinctrl/pinctrl-zynq.c b/drivers/pinctrl/pinctrl-zynq.c index e0ecffcbe11f..b51a46dfdcc3 100644 --- a/drivers/pinctrl/pinctrl-zynq.c +++ b/drivers/pinctrl/pinctrl-zynq.c @@ -247,6 +247,8 @@ static const unsigned int smc0_nor_addr25_pins[] = {1}; static const unsigned int smc0_nand_pins[] = {0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21, 22, 23}; +static const unsigned int smc0_nand8_pins[] = {0, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14}; /* Note: CAN MIO clock inputs are modeled in the clock framework */ static const unsigned int can0_0_pins[] = {10, 11}; static const unsigned int can0_1_pins[] = {14, 15}; @@ -445,6 +447,7 @@ static const struct zynq_pctrl_group zynq_pctrl_groups[] = { DEFINE_ZYNQ_PINCTRL_GRP(smc0_nor_cs1), DEFINE_ZYNQ_PINCTRL_GRP(smc0_nor_addr25), DEFINE_ZYNQ_PINCTRL_GRP(smc0_nand), + DEFINE_ZYNQ_PINCTRL_GRP(smc0_nand8), DEFINE_ZYNQ_PINCTRL_GRP(can0_0), DEFINE_ZYNQ_PINCTRL_GRP(can0_1), DEFINE_ZYNQ_PINCTRL_GRP(can0_2), @@ -709,7 +712,8 @@ static const char * const sdio1_wp_groups[] = {"gpio0_0_grp", static const char * const smc0_nor_groups[] = {"smc0_nor_grp"}; static const char * const smc0_nor_cs1_groups[] = {"smc0_nor_cs1_grp"}; static const char * const smc0_nor_addr25_groups[] = {"smc0_nor_addr25_grp"}; -static const char * const smc0_nand_groups[] = {"smc0_nand_grp"}; +static const char * const smc0_nand_groups[] = {"smc0_nand_grp", + "smc0_nand8_grp"}; static const char * const can0_groups[] = {"can0_0_grp", "can0_1_grp", "can0_2_grp", "can0_3_grp", "can0_4_grp", "can0_5_grp", "can0_6_grp", "can0_7_grp", "can0_8_grp", "can0_9_grp", diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig index 93ef268d5ccd..3ebdc01f53c0 100644 --- a/drivers/pinctrl/qcom/Kconfig +++ b/drivers/pinctrl/qcom/Kconfig @@ -79,6 +79,15 @@ config PINCTRL_MSM8916 This is the pinctrl, pinmux, pinconf and gpiolib driver for the Qualcomm TLMM block found on the Qualcomm 8916 platform. +config PINCTRL_MSM8994 + tristate "Qualcomm 8994 pin controller driver" + depends on GPIOLIB && OF + select PINCTRL_MSM + help + This is the pinctrl, pinmux, pinconf and gpiolib driver for the + Qualcomm TLMM block found in the Qualcomm 8994 platform. The + Qualcomm 8992 platform is also supported by this driver. + config PINCTRL_MSM8996 tristate "Qualcomm MSM8996 pin controller driver" depends on GPIOLIB && OF diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile index 8319e11cecb5..ab47764dbc5c 100644 --- a/drivers/pinctrl/qcom/Makefile +++ b/drivers/pinctrl/qcom/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_PINCTRL_MSM8660) += pinctrl-msm8660.o obj-$(CONFIG_PINCTRL_MSM8960) += pinctrl-msm8960.o obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o obj-$(CONFIG_PINCTRL_MSM8916) += pinctrl-msm8916.o +obj-$(CONFIG_PINCTRL_MSM8994) += pinctrl-msm8994.o obj-$(CONFIG_PINCTRL_MSM8996) += pinctrl-msm8996.o obj-$(CONFIG_PINCTRL_QDF2XXX) += pinctrl-qdf2xxx.o obj-$(CONFIG_PINCTRL_MDM9615) += pinctrl-mdm9615.o diff --git a/drivers/pinctrl/qcom/pinctrl-msm8994.c b/drivers/pinctrl/qcom/pinctrl-msm8994.c new file mode 100644 index 000000000000..8e16d9ae0c39 --- /dev/null +++ b/drivers/pinctrl/qcom/pinctrl-msm8994.c @@ -0,0 +1,1379 @@ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/pinctrl/pinctrl.h> + +#include "pinctrl-msm.h" + +#define FUNCTION(fname) \ + [MSM_MUX_##fname] = { \ + .name = #fname, \ + .groups = fname##_groups, \ + .ngroups = ARRAY_SIZE(fname##_groups), \ + } + +#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11) \ + { \ + .name = "gpio" #id, \ + .pins = gpio##id##_pins, \ + .npins = ARRAY_SIZE(gpio##id##_pins), \ + .funcs = (int[]){ \ + MSM_MUX_gpio, \ + MSM_MUX_##f1, \ + MSM_MUX_##f2, \ + MSM_MUX_##f3, \ + MSM_MUX_##f4, \ + MSM_MUX_##f5, \ + MSM_MUX_##f6, \ + MSM_MUX_##f7, \ + MSM_MUX_##f8, \ + MSM_MUX_##f9, \ + MSM_MUX_##f10, \ + MSM_MUX_##f11 \ + }, \ + .nfuncs = 12, \ + .ctl_reg = 0x1000 + 0x10 * id, \ + .io_reg = 0x1004 + 0x10 * id, \ + .intr_cfg_reg = 0x1008 + 0x10 * id, \ + .intr_status_reg = 0x100c + 0x10 * id, \ + .intr_target_reg = 0x1008 + 0x10 * id, \ + .mux_bit = 2, \ + .pull_bit = 0, \ + .drv_bit = 6, \ + .oe_bit = 9, \ + .in_bit = 0, \ + .out_bit = 1, \ + .intr_enable_bit = 0, \ + .intr_status_bit = 0, \ + .intr_target_bit = 5, \ + .intr_target_kpss_val = 4, \ + .intr_raw_status_bit = 4, \ + .intr_polarity_bit = 1, \ + .intr_detection_bit = 2, \ + .intr_detection_width = 2, \ + } + +#define SDC_PINGROUP(pg_name, ctl, pull, drv) \ + { \ + .name = #pg_name, \ + .pins = pg_name##_pins, \ + .npins = ARRAY_SIZE(pg_name##_pins), \ + .ctl_reg = ctl, \ + .io_reg = 0, \ + .intr_cfg_reg = 0, \ + .intr_status_reg = 0, \ + .intr_target_reg = 0, \ + .mux_bit = -1, \ + .pull_bit = pull, \ + .drv_bit = drv, \ + .oe_bit = -1, \ + .in_bit = -1, \ + .out_bit = -1, \ + .intr_enable_bit = -1, \ + .intr_status_bit = -1, \ + .intr_target_bit = -1, \ + .intr_target_kpss_val = -1, \ + .intr_raw_status_bit = -1, \ + .intr_polarity_bit = -1, \ + .intr_detection_bit = -1, \ + .intr_detection_width = -1, \ + } +static const struct pinctrl_pin_desc msm8994_pins[] = { + PINCTRL_PIN(0, "GPIO_0"), + PINCTRL_PIN(1, "GPIO_1"), + PINCTRL_PIN(2, "GPIO_2"), + PINCTRL_PIN(3, "GPIO_3"), + PINCTRL_PIN(4, "GPIO_4"), + PINCTRL_PIN(5, "GPIO_5"), + PINCTRL_PIN(6, "GPIO_6"), + PINCTRL_PIN(7, "GPIO_7"), + PINCTRL_PIN(8, "GPIO_8"), + PINCTRL_PIN(9, "GPIO_9"), + PINCTRL_PIN(10, "GPIO_10"), + PINCTRL_PIN(11, "GPIO_11"), + PINCTRL_PIN(12, "GPIO_12"), + PINCTRL_PIN(13, "GPIO_13"), + PINCTRL_PIN(14, "GPIO_14"), + PINCTRL_PIN(15, "GPIO_15"), + PINCTRL_PIN(16, "GPIO_16"), + PINCTRL_PIN(17, "GPIO_17"), + PINCTRL_PIN(18, "GPIO_18"), + PINCTRL_PIN(19, "GPIO_19"), + PINCTRL_PIN(20, "GPIO_20"), + PINCTRL_PIN(21, "GPIO_21"), + PINCTRL_PIN(22, "GPIO_22"), + PINCTRL_PIN(23, "GPIO_23"), + PINCTRL_PIN(24, "GPIO_24"), + PINCTRL_PIN(25, "GPIO_25"), + PINCTRL_PIN(26, "GPIO_26"), + PINCTRL_PIN(27, "GPIO_27"), + PINCTRL_PIN(28, "GPIO_28"), + PINCTRL_PIN(29, "GPIO_29"), + PINCTRL_PIN(30, "GPIO_30"), + PINCTRL_PIN(31, "GPIO_31"), + PINCTRL_PIN(32, "GPIO_32"), + PINCTRL_PIN(33, "GPIO_33"), + PINCTRL_PIN(34, "GPIO_34"), + PINCTRL_PIN(35, "GPIO_35"), + PINCTRL_PIN(36, "GPIO_36"), + PINCTRL_PIN(37, "GPIO_37"), + PINCTRL_PIN(38, "GPIO_38"), + PINCTRL_PIN(39, "GPIO_39"), + PINCTRL_PIN(40, "GPIO_40"), + PINCTRL_PIN(41, "GPIO_41"), + PINCTRL_PIN(42, "GPIO_42"), + PINCTRL_PIN(43, "GPIO_43"), + PINCTRL_PIN(44, "GPIO_44"), + PINCTRL_PIN(45, "GPIO_45"), + PINCTRL_PIN(46, "GPIO_46"), + PINCTRL_PIN(47, "GPIO_47"), + PINCTRL_PIN(48, "GPIO_48"), + PINCTRL_PIN(49, "GPIO_49"), + PINCTRL_PIN(50, "GPIO_50"), + PINCTRL_PIN(51, "GPIO_51"), + PINCTRL_PIN(52, "GPIO_52"), + PINCTRL_PIN(53, "GPIO_53"), + PINCTRL_PIN(54, "GPIO_54"), + PINCTRL_PIN(55, "GPIO_55"), + PINCTRL_PIN(56, "GPIO_56"), + PINCTRL_PIN(57, "GPIO_57"), + PINCTRL_PIN(58, "GPIO_58"), + PINCTRL_PIN(59, "GPIO_59"), + PINCTRL_PIN(60, "GPIO_60"), + PINCTRL_PIN(61, "GPIO_61"), + PINCTRL_PIN(62, "GPIO_62"), + PINCTRL_PIN(63, "GPIO_63"), + PINCTRL_PIN(64, "GPIO_64"), + PINCTRL_PIN(65, "GPIO_65"), + PINCTRL_PIN(66, "GPIO_66"), + PINCTRL_PIN(67, "GPIO_67"), + PINCTRL_PIN(68, "GPIO_68"), + PINCTRL_PIN(69, "GPIO_69"), + PINCTRL_PIN(70, "GPIO_70"), + PINCTRL_PIN(71, "GPIO_71"), + PINCTRL_PIN(72, "GPIO_72"), + PINCTRL_PIN(73, "GPIO_73"), + PINCTRL_PIN(74, "GPIO_74"), + PINCTRL_PIN(75, "GPIO_75"), + PINCTRL_PIN(76, "GPIO_76"), + PINCTRL_PIN(77, "GPIO_77"), + PINCTRL_PIN(78, "GPIO_78"), + PINCTRL_PIN(79, "GPIO_79"), + PINCTRL_PIN(80, "GPIO_80"), + PINCTRL_PIN(81, "GPIO_81"), + PINCTRL_PIN(82, "GPIO_82"), + PINCTRL_PIN(83, "GPIO_83"), + PINCTRL_PIN(84, "GPIO_84"), + PINCTRL_PIN(85, "GPIO_85"), + PINCTRL_PIN(86, "GPIO_86"), + PINCTRL_PIN(87, "GPIO_87"), + PINCTRL_PIN(88, "GPIO_88"), + PINCTRL_PIN(89, "GPIO_89"), + PINCTRL_PIN(90, "GPIO_90"), + PINCTRL_PIN(91, "GPIO_91"), + PINCTRL_PIN(92, "GPIO_92"), + PINCTRL_PIN(93, "GPIO_93"), + PINCTRL_PIN(94, "GPIO_94"), + PINCTRL_PIN(95, "GPIO_95"), + PINCTRL_PIN(96, "GPIO_96"), + PINCTRL_PIN(97, "GPIO_97"), + PINCTRL_PIN(98, "GPIO_98"), + PINCTRL_PIN(99, "GPIO_99"), + PINCTRL_PIN(100, "GPIO_100"), + PINCTRL_PIN(101, "GPIO_101"), + PINCTRL_PIN(102, "GPIO_102"), + PINCTRL_PIN(103, "GPIO_103"), + PINCTRL_PIN(104, "GPIO_104"), + PINCTRL_PIN(105, "GPIO_105"), + PINCTRL_PIN(106, "GPIO_106"), + PINCTRL_PIN(107, "GPIO_107"), + PINCTRL_PIN(108, "GPIO_108"), + PINCTRL_PIN(109, "GPIO_109"), + PINCTRL_PIN(110, "GPIO_110"), + PINCTRL_PIN(111, "GPIO_111"), + PINCTRL_PIN(112, "GPIO_112"), + PINCTRL_PIN(113, "GPIO_113"), + PINCTRL_PIN(114, "GPIO_114"), + PINCTRL_PIN(115, "GPIO_115"), + PINCTRL_PIN(116, "GPIO_116"), + PINCTRL_PIN(117, "GPIO_117"), + PINCTRL_PIN(118, "GPIO_118"), + PINCTRL_PIN(119, "GPIO_119"), + PINCTRL_PIN(120, "GPIO_120"), + PINCTRL_PIN(121, "GPIO_121"), + PINCTRL_PIN(122, "GPIO_122"), + PINCTRL_PIN(123, "GPIO_123"), + PINCTRL_PIN(124, "GPIO_124"), + PINCTRL_PIN(125, "GPIO_125"), + PINCTRL_PIN(126, "GPIO_126"), + PINCTRL_PIN(127, "GPIO_127"), + PINCTRL_PIN(128, "GPIO_128"), + PINCTRL_PIN(129, "GPIO_129"), + PINCTRL_PIN(130, "GPIO_130"), + PINCTRL_PIN(131, "GPIO_131"), + PINCTRL_PIN(132, "GPIO_132"), + PINCTRL_PIN(133, "GPIO_133"), + PINCTRL_PIN(134, "GPIO_134"), + PINCTRL_PIN(135, "GPIO_135"), + PINCTRL_PIN(136, "GPIO_136"), + PINCTRL_PIN(137, "GPIO_137"), + PINCTRL_PIN(138, "GPIO_138"), + PINCTRL_PIN(139, "GPIO_139"), + PINCTRL_PIN(140, "GPIO_140"), + PINCTRL_PIN(141, "GPIO_141"), + PINCTRL_PIN(142, "GPIO_142"), + PINCTRL_PIN(143, "GPIO_143"), + PINCTRL_PIN(144, "GPIO_144"), + PINCTRL_PIN(145, "GPIO_145"), + PINCTRL_PIN(146, "SDC1_RCLK"), + PINCTRL_PIN(147, "SDC1_CLK"), + PINCTRL_PIN(148, "SDC1_CMD"), + PINCTRL_PIN(149, "SDC1_DATA"), + PINCTRL_PIN(150, "SDC2_CLK"), + PINCTRL_PIN(151, "SDC2_CMD"), + PINCTRL_PIN(152, "SDC2_DATA"), + PINCTRL_PIN(153, "SDC3_CLK"), + PINCTRL_PIN(154, "SDC3_CMD"), + PINCTRL_PIN(155, "SDC3_DATA"), +}; + +#define DECLARE_MSM_GPIO_PINS(pin) \ + static const unsigned int gpio##pin##_pins[] = { pin } +DECLARE_MSM_GPIO_PINS(0); +DECLARE_MSM_GPIO_PINS(1); +DECLARE_MSM_GPIO_PINS(2); +DECLARE_MSM_GPIO_PINS(3); +DECLARE_MSM_GPIO_PINS(4); +DECLARE_MSM_GPIO_PINS(5); +DECLARE_MSM_GPIO_PINS(6); +DECLARE_MSM_GPIO_PINS(7); +DECLARE_MSM_GPIO_PINS(8); +DECLARE_MSM_GPIO_PINS(9); +DECLARE_MSM_GPIO_PINS(10); +DECLARE_MSM_GPIO_PINS(11); +DECLARE_MSM_GPIO_PINS(12); +DECLARE_MSM_GPIO_PINS(13); +DECLARE_MSM_GPIO_PINS(14); +DECLARE_MSM_GPIO_PINS(15); +DECLARE_MSM_GPIO_PINS(16); +DECLARE_MSM_GPIO_PINS(17); +DECLARE_MSM_GPIO_PINS(18); +DECLARE_MSM_GPIO_PINS(19); +DECLARE_MSM_GPIO_PINS(20); +DECLARE_MSM_GPIO_PINS(21); +DECLARE_MSM_GPIO_PINS(22); +DECLARE_MSM_GPIO_PINS(23); +DECLARE_MSM_GPIO_PINS(24); +DECLARE_MSM_GPIO_PINS(25); +DECLARE_MSM_GPIO_PINS(26); +DECLARE_MSM_GPIO_PINS(27); +DECLARE_MSM_GPIO_PINS(28); +DECLARE_MSM_GPIO_PINS(29); +DECLARE_MSM_GPIO_PINS(30); +DECLARE_MSM_GPIO_PINS(31); +DECLARE_MSM_GPIO_PINS(32); +DECLARE_MSM_GPIO_PINS(33); +DECLARE_MSM_GPIO_PINS(34); +DECLARE_MSM_GPIO_PINS(35); +DECLARE_MSM_GPIO_PINS(36); +DECLARE_MSM_GPIO_PINS(37); +DECLARE_MSM_GPIO_PINS(38); +DECLARE_MSM_GPIO_PINS(39); +DECLARE_MSM_GPIO_PINS(40); +DECLARE_MSM_GPIO_PINS(41); +DECLARE_MSM_GPIO_PINS(42); +DECLARE_MSM_GPIO_PINS(43); +DECLARE_MSM_GPIO_PINS(44); +DECLARE_MSM_GPIO_PINS(45); +DECLARE_MSM_GPIO_PINS(46); +DECLARE_MSM_GPIO_PINS(47); +DECLARE_MSM_GPIO_PINS(48); +DECLARE_MSM_GPIO_PINS(49); +DECLARE_MSM_GPIO_PINS(50); +DECLARE_MSM_GPIO_PINS(51); +DECLARE_MSM_GPIO_PINS(52); +DECLARE_MSM_GPIO_PINS(53); +DECLARE_MSM_GPIO_PINS(54); +DECLARE_MSM_GPIO_PINS(55); +DECLARE_MSM_GPIO_PINS(56); +DECLARE_MSM_GPIO_PINS(57); +DECLARE_MSM_GPIO_PINS(58); +DECLARE_MSM_GPIO_PINS(59); +DECLARE_MSM_GPIO_PINS(60); +DECLARE_MSM_GPIO_PINS(61); +DECLARE_MSM_GPIO_PINS(62); +DECLARE_MSM_GPIO_PINS(63); +DECLARE_MSM_GPIO_PINS(64); +DECLARE_MSM_GPIO_PINS(65); +DECLARE_MSM_GPIO_PINS(66); +DECLARE_MSM_GPIO_PINS(67); +DECLARE_MSM_GPIO_PINS(68); +DECLARE_MSM_GPIO_PINS(69); +DECLARE_MSM_GPIO_PINS(70); +DECLARE_MSM_GPIO_PINS(71); +DECLARE_MSM_GPIO_PINS(72); +DECLARE_MSM_GPIO_PINS(73); +DECLARE_MSM_GPIO_PINS(74); +DECLARE_MSM_GPIO_PINS(75); +DECLARE_MSM_GPIO_PINS(76); +DECLARE_MSM_GPIO_PINS(77); +DECLARE_MSM_GPIO_PINS(78); +DECLARE_MSM_GPIO_PINS(79); +DECLARE_MSM_GPIO_PINS(80); +DECLARE_MSM_GPIO_PINS(81); +DECLARE_MSM_GPIO_PINS(82); +DECLARE_MSM_GPIO_PINS(83); +DECLARE_MSM_GPIO_PINS(84); +DECLARE_MSM_GPIO_PINS(85); +DECLARE_MSM_GPIO_PINS(86); +DECLARE_MSM_GPIO_PINS(87); +DECLARE_MSM_GPIO_PINS(88); +DECLARE_MSM_GPIO_PINS(89); +DECLARE_MSM_GPIO_PINS(90); +DECLARE_MSM_GPIO_PINS(91); +DECLARE_MSM_GPIO_PINS(92); +DECLARE_MSM_GPIO_PINS(93); +DECLARE_MSM_GPIO_PINS(94); +DECLARE_MSM_GPIO_PINS(95); +DECLARE_MSM_GPIO_PINS(96); +DECLARE_MSM_GPIO_PINS(97); +DECLARE_MSM_GPIO_PINS(98); +DECLARE_MSM_GPIO_PINS(99); +DECLARE_MSM_GPIO_PINS(100); +DECLARE_MSM_GPIO_PINS(101); +DECLARE_MSM_GPIO_PINS(102); +DECLARE_MSM_GPIO_PINS(103); +DECLARE_MSM_GPIO_PINS(104); +DECLARE_MSM_GPIO_PINS(105); +DECLARE_MSM_GPIO_PINS(106); +DECLARE_MSM_GPIO_PINS(107); +DECLARE_MSM_GPIO_PINS(108); +DECLARE_MSM_GPIO_PINS(109); +DECLARE_MSM_GPIO_PINS(110); +DECLARE_MSM_GPIO_PINS(111); +DECLARE_MSM_GPIO_PINS(112); +DECLARE_MSM_GPIO_PINS(113); +DECLARE_MSM_GPIO_PINS(114); +DECLARE_MSM_GPIO_PINS(115); +DECLARE_MSM_GPIO_PINS(116); +DECLARE_MSM_GPIO_PINS(117); +DECLARE_MSM_GPIO_PINS(118); +DECLARE_MSM_GPIO_PINS(119); +DECLARE_MSM_GPIO_PINS(120); +DECLARE_MSM_GPIO_PINS(121); +DECLARE_MSM_GPIO_PINS(122); +DECLARE_MSM_GPIO_PINS(123); +DECLARE_MSM_GPIO_PINS(124); +DECLARE_MSM_GPIO_PINS(125); +DECLARE_MSM_GPIO_PINS(126); +DECLARE_MSM_GPIO_PINS(127); +DECLARE_MSM_GPIO_PINS(128); +DECLARE_MSM_GPIO_PINS(129); +DECLARE_MSM_GPIO_PINS(130); +DECLARE_MSM_GPIO_PINS(131); +DECLARE_MSM_GPIO_PINS(132); +DECLARE_MSM_GPIO_PINS(133); +DECLARE_MSM_GPIO_PINS(134); +DECLARE_MSM_GPIO_PINS(135); +DECLARE_MSM_GPIO_PINS(136); +DECLARE_MSM_GPIO_PINS(137); +DECLARE_MSM_GPIO_PINS(138); +DECLARE_MSM_GPIO_PINS(139); +DECLARE_MSM_GPIO_PINS(140); +DECLARE_MSM_GPIO_PINS(141); +DECLARE_MSM_GPIO_PINS(142); +DECLARE_MSM_GPIO_PINS(143); +DECLARE_MSM_GPIO_PINS(144); +DECLARE_MSM_GPIO_PINS(145); + +static const unsigned int sdc1_rclk_pins[] = { 146 }; +static const unsigned int sdc1_clk_pins[] = { 147 }; +static const unsigned int sdc1_cmd_pins[] = { 148 }; +static const unsigned int sdc1_data_pins[] = { 149 }; +static const unsigned int sdc2_clk_pins[] = { 150 }; +static const unsigned int sdc2_cmd_pins[] = { 151 }; +static const unsigned int sdc2_data_pins[] = { 152 }; +static const unsigned int sdc3_clk_pins[] = { 153 }; +static const unsigned int sdc3_cmd_pins[] = { 154 }; +static const unsigned int sdc3_data_pins[] = { 155 }; + +enum msm8994_functions { + MSM_MUX_audio_ref_clk, + MSM_MUX_blsp_i2c1, + MSM_MUX_blsp_i2c2, + MSM_MUX_blsp_i2c3, + MSM_MUX_blsp_i2c4, + MSM_MUX_blsp_i2c5, + MSM_MUX_blsp_i2c6, + MSM_MUX_blsp_i2c7, + MSM_MUX_blsp_i2c8, + MSM_MUX_blsp_i2c9, + MSM_MUX_blsp_i2c10, + MSM_MUX_blsp_i2c11, + MSM_MUX_blsp_i2c12, + MSM_MUX_blsp_spi1, + MSM_MUX_blsp_spi1_cs1, + MSM_MUX_blsp_spi1_cs2, + MSM_MUX_blsp_spi1_cs3, + MSM_MUX_blsp_spi2, + MSM_MUX_blsp_spi2_cs1, + MSM_MUX_blsp_spi2_cs2, + MSM_MUX_blsp_spi2_cs3, + MSM_MUX_blsp_spi3, + MSM_MUX_blsp_spi4, + MSM_MUX_blsp_spi5, + MSM_MUX_blsp_spi6, + MSM_MUX_blsp_spi7, + MSM_MUX_blsp_spi8, + MSM_MUX_blsp_spi9, + MSM_MUX_blsp_spi10, + MSM_MUX_blsp_spi10_cs1, + MSM_MUX_blsp_spi10_cs2, + MSM_MUX_blsp_spi10_cs3, + MSM_MUX_blsp_spi11, + MSM_MUX_blsp_spi12, + MSM_MUX_blsp_uart1, + MSM_MUX_blsp_uart2, + MSM_MUX_blsp_uart3, + MSM_MUX_blsp_uart4, + MSM_MUX_blsp_uart5, + MSM_MUX_blsp_uart6, + MSM_MUX_blsp_uart7, + MSM_MUX_blsp_uart8, + MSM_MUX_blsp_uart9, + MSM_MUX_blsp_uart10, + MSM_MUX_blsp_uart11, + MSM_MUX_blsp_uart12, + MSM_MUX_blsp_uim1, + MSM_MUX_blsp_uim2, + MSM_MUX_blsp_uim3, + MSM_MUX_blsp_uim4, + MSM_MUX_blsp_uim5, + MSM_MUX_blsp_uim6, + MSM_MUX_blsp_uim7, + MSM_MUX_blsp_uim8, + MSM_MUX_blsp_uim9, + MSM_MUX_blsp_uim10, + MSM_MUX_blsp_uim11, + MSM_MUX_blsp_uim12, + MSM_MUX_blsp11_i2c_scl_b, + MSM_MUX_blsp11_i2c_sda_b, + MSM_MUX_blsp11_uart_rx_b, + MSM_MUX_blsp11_uart_tx_b, + MSM_MUX_cam_mclk0, + MSM_MUX_cam_mclk1, + MSM_MUX_cam_mclk2, + MSM_MUX_cam_mclk3, + MSM_MUX_cci_async_in0, + MSM_MUX_cci_async_in1, + MSM_MUX_cci_async_in2, + MSM_MUX_cci_i2c0, + MSM_MUX_cci_i2c1, + MSM_MUX_cci_timer0, + MSM_MUX_cci_timer1, + MSM_MUX_cci_timer2, + MSM_MUX_cci_timer3, + MSM_MUX_cci_timer4, + MSM_MUX_gcc_gp1_clk_a, + MSM_MUX_gcc_gp1_clk_b, + MSM_MUX_gcc_gp2_clk_a, + MSM_MUX_gcc_gp2_clk_b, + MSM_MUX_gcc_gp3_clk_a, + MSM_MUX_gcc_gp3_clk_b, + MSM_MUX_gp_mn, + MSM_MUX_gp_pdm0, + MSM_MUX_gp_pdm1, + MSM_MUX_gp_pdm2, + MSM_MUX_gp0_clk, + MSM_MUX_gp1_clk, + MSM_MUX_gps_tx, + MSM_MUX_gsm_tx, + MSM_MUX_hdmi_cec, + MSM_MUX_hdmi_ddc, + MSM_MUX_hdmi_hpd, + MSM_MUX_hdmi_rcv, + MSM_MUX_mdp_vsync, + MSM_MUX_mss_lte, + MSM_MUX_nav_pps, + MSM_MUX_nav_tsync, + MSM_MUX_qdss_cti_trig_in_a, + MSM_MUX_qdss_cti_trig_in_b, + MSM_MUX_qdss_cti_trig_in_c, + MSM_MUX_qdss_cti_trig_in_d, + MSM_MUX_qdss_cti_trig_out_a, + MSM_MUX_qdss_cti_trig_out_b, + MSM_MUX_qdss_cti_trig_out_c, + MSM_MUX_qdss_cti_trig_out_d, + MSM_MUX_qdss_traceclk_a, + MSM_MUX_qdss_traceclk_b, + MSM_MUX_qdss_tracectl_a, + MSM_MUX_qdss_tracectl_b, + MSM_MUX_qdss_tracedata_a, + MSM_MUX_qdss_tracedata_b, + MSM_MUX_qua_mi2s, + MSM_MUX_pci_e0, + MSM_MUX_pci_e1, + MSM_MUX_pri_mi2s, + MSM_MUX_sdc4, + MSM_MUX_sec_mi2s, + MSM_MUX_slimbus, + MSM_MUX_spkr_i2s, + MSM_MUX_ter_mi2s, + MSM_MUX_tsif1, + MSM_MUX_tsif2, + MSM_MUX_uim1, + MSM_MUX_uim2, + MSM_MUX_uim3, + MSM_MUX_uim4, + MSM_MUX_uim_batt_alarm, + MSM_MUX_gpio, + MSM_MUX_NA, +}; + +static const char * const gpio_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7", + "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14", + "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21", + "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", + "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35", + "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42", + "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49", + "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56", + "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63", + "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70", + "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77", + "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84", + "gpio85", "gpio86", "gpio87", "gpio88", "gpio89", "gpio90", "gpio91", + "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97", "gpio98", + "gpio99", "gpio100", "gpio101", "gpio102", "gpio103", "gpio104", + "gpio105", "gpio106", "gpio107", "gpio108", "gpio109", "gpio110", + "gpio111", "gpio112", "gpio113", "gpio114", "gpio115", "gpio116", + "gpio117", "gpio118", "gpio119", "gpio120", "gpio121", "gpio122", + "gpio123", "gpio124", "gpio125", "gpio126", "gpio127", "gpio128", + "gpio129", "gpio130", "gpio131", "gpio132", "gpio133", "gpio134", + "gpio135", "gpio136", "gpio137", "gpio138", "gpio139", "gpio140", + "gpio141", "gpio142", "gpio143", "gpio144", "gpio145", +}; + +static const char * const blsp_spi1_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3" +}; +static const char * const blsp_uart1_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3" +}; +static const char * const blsp_uim1_groups[] = { + "gpio0", "gpio1" +}; +static const char * const hdmi_rcv_groups[] = { + "gpio0" +}; +static const char * const blsp_i2c1_groups[] = { + "gpio2", "gpio3" +}; +static const char * const blsp_spi2_groups[] = { + "gpio4", "gpio5", "gpio6", "gpio7" +}; +static const char * const blsp_uart2_groups[] = { + "gpio4", "gpio5", "gpio6", "gpio7" +}; +static const char * const blsp_uim2_groups[] = { + "gpio4", "gpio5" +}; +static const char * const qdss_cti_trig_out_b_groups[] = { + "gpio4", +}; +static const char * const qdss_cti_trig_in_b_groups[] = { + "gpio5", +}; +static const char * const blsp_i2c2_groups[] = { + "gpio6", "gpio7" +}; +static const char * const blsp_spi3_groups[] = { + "gpio8", "gpio9", "gpio10", "gpio11" +}; +static const char * const blsp_uart3_groups[] = { + "gpio8", "gpio9", "gpio10", "gpio11" +}; +static const char * const blsp_uim3_groups[] = { + "gpio8", "gpio9" +}; +static const char * const blsp_spi1_cs1_groups[] = { + "gpio8" +}; +static const char * const blsp_spi1_cs2_groups[] = { + "gpio9", "gpio11" +}; +static const char * const mdp_vsync_groups[] = { + "gpio10", "gpio11", "gpio12" +}; +static const char * const blsp_i2c3_groups[] = { + "gpio10", "gpio11" +}; +static const char * const blsp_spi1_cs3_groups[] = { + "gpio10" +}; +static const char * const qdss_tracedata_b_groups[] = { + "gpio13", "gpio14", "gpio15", "gpio16", "gpio17", "gpio18", + "gpio19", "gpio21", "gpio22", "gpio23", "gpio25", "gpio26", + "gpio57", "gpio58", "gpio92", "gpio93", +}; +static const char * const cam_mclk0_groups[] = { + "gpio13" +}; +static const char * const cam_mclk1_groups[] = { + "gpio14" +}; +static const char * const cam_mclk2_groups[] = { + "gpio15" +}; +static const char * const cam_mclk3_groups[] = { + "gpio16" +}; +static const char * const cci_i2c0_groups[] = { + "gpio17", "gpio18" +}; +static const char * const blsp_spi4_groups[] = { + "gpio17", "gpio18", "gpio19", "gpio20" +}; +static const char * const blsp_uart4_groups[] = { + "gpio17", "gpio18", "gpio19", "gpio20" +}; +static const char * const blsp_uim4_groups[] = { + "gpio17", "gpio18" +}; +static const char * const cci_i2c1_groups[] = { + "gpio19", "gpio20" +}; +static const char * const blsp_i2c4_groups[] = { + "gpio19", "gpio20" +}; +static const char * const cci_timer0_groups[] = { + "gpio21" +}; +static const char * const blsp_spi5_groups[] = { + "gpio21", "gpio22", "gpio23", "gpio24" +}; +static const char * const blsp_uart5_groups[] = { + "gpio21", "gpio22", "gpio23", "gpio24" +}; +static const char * const blsp_uim5_groups[] = { + "gpio21", "gpio22" +}; +static const char * const cci_timer1_groups[] = { + "gpio22" +}; +static const char * const cci_timer2_groups[] = { + "gpio23" +}; +static const char * const blsp_i2c5_groups[] = { + "gpio23", "gpio24" +}; +static const char * const cci_timer3_groups[] = { + "gpio24" +}; +static const char * const cci_async_in1_groups[] = { + "gpio24" +}; +static const char * const cci_timer4_groups[] = { + "gpio25" +}; +static const char * const cci_async_in2_groups[] = { + "gpio25" +}; +static const char * const blsp_spi6_groups[] = { + "gpio25", "gpio26", "gpio27", "gpio28" +}; +static const char * const blsp_uart6_groups[] = { + "gpio25", "gpio26", "gpio27", "gpio28" +}; +static const char * const blsp_uim6_groups[] = { + "gpio25", "gpio26" +}; +static const char * const cci_async_in0_groups[] = { + "gpio26" +}; +static const char * const gp0_clk_groups[] = { + "gpio26" +}; +static const char * const gp1_clk_groups[] = { + "gpio27", "gpio57", "gpio78" +}; +static const char * const blsp_i2c6_groups[] = { + "gpio27", "gpio28" +}; +static const char * const qdss_tracectl_a_groups[] = { + "gpio27", +}; +static const char * const qdss_traceclk_a_groups[] = { + "gpio28", +}; +static const char * const gp_mn_groups[] = { + "gpio29" +}; +static const char * const hdmi_cec_groups[] = { + "gpio31" +}; +static const char * const hdmi_ddc_groups[] = { + "gpio32", "gpio33" +}; +static const char * const hdmi_hpd_groups[] = { + "gpio34" +}; +static const char * const uim3_groups[] = { + "gpio35", "gpio36", "gpio37", "gpio38" +}; +static const char * const pci_e1_groups[] = { + "gpio35", "gpio36", +}; +static const char * const blsp_spi7_groups[] = { + "gpio41", "gpio42", "gpio43", "gpio44" +}; +static const char * const blsp_uart7_groups[] = { + "gpio41", "gpio42", "gpio43", "gpio44" +}; +static const char * const blsp_uim7_groups[] = { + "gpio41", "gpio42" +}; +static const char * const qdss_cti_trig_out_c_groups[] = { + "gpio41", +}; +static const char * const qdss_cti_trig_in_c_groups[] = { + "gpio42", +}; +static const char * const blsp_i2c7_groups[] = { + "gpio43", "gpio44" +}; +static const char * const blsp_spi8_groups[] = { + "gpio45", "gpio46", "gpio47", "gpio48" +}; +static const char * const blsp_uart8_groups[] = { + "gpio45", "gpio46", "gpio47", "gpio48" +}; +static const char * const blsp_uim8_groups[] = { + "gpio45", "gpio46" +}; +static const char * const blsp_i2c8_groups[] = { + "gpio47", "gpio48" +}; +static const char * const blsp_spi10_cs1_groups[] = { + "gpio47", "gpio67" +}; +static const char * const blsp_spi10_cs2_groups[] = { + "gpio48", "gpio68" +}; +static const char * const uim2_groups[] = { + "gpio49", "gpio50", "gpio51", "gpio52" +}; +static const char * const blsp_spi9_groups[] = { + "gpio49", "gpio50", "gpio51", "gpio52" +}; +static const char * const blsp_uart9_groups[] = { + "gpio49", "gpio50", "gpio51", "gpio52" +}; +static const char * const blsp_uim9_groups[] = { + "gpio49", "gpio50" +}; +static const char * const blsp_i2c9_groups[] = { + "gpio51", "gpio52" +}; +static const char * const pci_e0_groups[] = { + "gpio53", "gpio54", +}; +static const char * const uim4_groups[] = { + "gpio53", "gpio54", "gpio55", "gpio56" +}; +static const char * const blsp_spi10_groups[] = { + "gpio53", "gpio54", "gpio55", "gpio56" +}; +static const char * const blsp_uart10_groups[] = { + "gpio53", "gpio54", "gpio55", "gpio56" +}; +static const char * const blsp_uim10_groups[] = { + "gpio53", "gpio54" +}; +static const char * const qdss_tracedata_a_groups[] = { + "gpio53", "gpio54", "gpio63", "gpio64", "gpio65", + "gpio66", "gpio67", "gpio74", "gpio75", "gpio76", + "gpio77", "gpio85", "gpio86", "gpio87", "gpio89", + "gpio90" +}; +static const char * const gp_pdm0_groups[] = { + "gpio54", "gpio95" +}; +static const char * const blsp_i2c10_groups[] = { + "gpio55", "gpio56" +}; +static const char * const qdss_cti_trig_in_a_groups[] = { + "gpio55", +}; +static const char * const qdss_cti_trig_out_a_groups[] = { + "gpio56", +}; +static const char * const qua_mi2s_groups[] = { + "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63", +}; +static const char * const gcc_gp1_clk_a_groups[] = { + "gpio57" +}; +static const char * const gcc_gp2_clk_a_groups[] = { + "gpio58" +}; +static const char * const gcc_gp3_clk_a_groups[] = { + "gpio59" +}; +static const char * const blsp_spi2_cs1_groups[] = { + "gpio62" +}; +static const char * const blsp_spi2_cs2_groups[] = { + "gpio63" +}; +static const char * const gp_pdm2_groups[] = { + "gpio63", "gpio79" +}; +static const char * const pri_mi2s_groups[] = { + "gpio64", "gpio65", "gpio66", "gpio67", "gpio68" +}; +static const char * const blsp_spi2_cs3_groups[] = { + "gpio66" +}; +static const char * const spkr_i2s_groups[] = { + "gpio69", "gpio70", "gpio71", "gpio72" +}; +static const char * const audio_ref_clk_groups[] = { + "gpio69" +}; +static const char * const slimbus_groups[] = { + "gpio70", "gpio71" +}; +static const char * const ter_mi2s_groups[] = { + "gpio73", "gpio74", "gpio75", "gpio76", "gpio77" +}; +static const char * const gp_pdm1_groups[] = { + "gpio74", "gpio86" +}; +static const char * const sec_mi2s_groups[] = { + "gpio78", "gpio79", "gpio80", "gpio81", "gpio82" +}; +static const char * const gcc_gp1_clk_b_groups[] = { + "gpio78" +}; +static const char * const blsp_spi11_groups[] = { + "gpio81", "gpio82", "gpio83", "gpio84" +}; +static const char * const blsp_uart11_groups[] = { + "gpio81", "gpio82", "gpio83", "gpio84" +}; +static const char * const blsp_uim11_groups[] = { + "gpio81", "gpio82" +}; +static const char * const gcc_gp2_clk_b_groups[] = { + "gpio81" +}; +static const char * const gcc_gp3_clk_b_groups[] = { + "gpio82" +}; +static const char * const blsp_i2c11_groups[] = { + "gpio83", "gpio84" +}; +static const char * const blsp_uart12_groups[] = { + "gpio85", "gpio86", "gpio87", "gpio88" +}; +static const char * const blsp_uim12_groups[] = { + "gpio85", "gpio86" +}; +static const char * const blsp_i2c12_groups[] = { + "gpio87", "gpio88" +}; +static const char * const blsp_spi12_groups[] = { + "gpio85", "gpio86", "gpio87", "gpio88" +}; +static const char * const tsif1_groups[] = { + "gpio89", "gpio90", "gpio91", "gpio110", "gpio111" +}; +static const char * const blsp_spi10_cs3_groups[] = { + "gpio90" +}; +static const char * const sdc4_groups[] = { + "gpio91", "gpio92", "gpio93", "gpio94", "gpio95", "gpio96" +}; +static const char * const qdss_traceclk_b_groups[] = { + "gpio91", +}; +static const char * const tsif2_groups[] = { + "gpio92", "gpio93", "gpio94", "gpio95", "gpio96" +}; +static const char * const qdss_tracectl_b_groups[] = { + "gpio94", +}; +static const char * const qdss_cti_trig_out_d_groups[] = { + "gpio95", +}; +static const char * const qdss_cti_trig_in_d_groups[] = { + "gpio96", +}; +static const char * const uim1_groups[] = { + "gpio97", "gpio98", "gpio99", "gpio100" +}; +static const char * const uim_batt_alarm_groups[] = { + "gpio101" +}; +static const char * const blsp11_uart_tx_b_groups[] = { + "gpio111" +}; +static const char * const blsp11_uart_rx_b_groups[] = { + "gpio112" +}; +static const char * const blsp11_i2c_sda_b_groups[] = { + "gpio113" +}; +static const char * const blsp11_i2c_scl_b_groups[] = { + "gpio114" +}; +static const char * const gsm_tx_groups[] = { + "gpio126", "gpio131", "gpio132", "gpio133" +}; +static const char * const nav_tsync_groups[] = { + "gpio127" +}; +static const char * const nav_pps_groups[] = { + "gpio127" +}; +static const char * const gps_tx_groups[] = { + "gpio130" +}; +static const char * const mss_lte_groups[] = { + "gpio134", "gpio135" +}; + +static const struct msm_function msm8994_functions[] = { + FUNCTION(audio_ref_clk), + FUNCTION(blsp_i2c1), + FUNCTION(blsp_i2c2), + FUNCTION(blsp_i2c3), + FUNCTION(blsp_i2c4), + FUNCTION(blsp_i2c5), + FUNCTION(blsp_i2c6), + FUNCTION(blsp_i2c7), + FUNCTION(blsp_i2c8), + FUNCTION(blsp_i2c9), + FUNCTION(blsp_i2c10), + FUNCTION(blsp_i2c11), + FUNCTION(blsp_i2c12), + FUNCTION(blsp_spi1), + FUNCTION(blsp_spi1_cs1), + FUNCTION(blsp_spi1_cs2), + FUNCTION(blsp_spi1_cs3), + FUNCTION(blsp_spi2), + FUNCTION(blsp_spi2_cs1), + FUNCTION(blsp_spi2_cs2), + FUNCTION(blsp_spi2_cs3), + FUNCTION(blsp_spi3), + FUNCTION(blsp_spi4), + FUNCTION(blsp_spi5), + FUNCTION(blsp_spi6), + FUNCTION(blsp_spi7), + FUNCTION(blsp_spi8), + FUNCTION(blsp_spi9), + FUNCTION(blsp_spi10), + FUNCTION(blsp_spi10_cs1), + FUNCTION(blsp_spi10_cs2), + FUNCTION(blsp_spi10_cs3), + FUNCTION(blsp_spi11), + FUNCTION(blsp_spi12), + FUNCTION(blsp_uart1), + FUNCTION(blsp_uart2), + FUNCTION(blsp_uart3), + FUNCTION(blsp_uart4), + FUNCTION(blsp_uart5), + FUNCTION(blsp_uart6), + FUNCTION(blsp_uart7), + FUNCTION(blsp_uart8), + FUNCTION(blsp_uart9), + FUNCTION(blsp_uart10), + FUNCTION(blsp_uart11), + FUNCTION(blsp_uart12), + FUNCTION(blsp_uim1), + FUNCTION(blsp_uim2), + FUNCTION(blsp_uim3), + FUNCTION(blsp_uim4), + FUNCTION(blsp_uim5), + FUNCTION(blsp_uim6), + FUNCTION(blsp_uim7), + FUNCTION(blsp_uim8), + FUNCTION(blsp_uim9), + FUNCTION(blsp_uim10), + FUNCTION(blsp_uim11), + FUNCTION(blsp_uim12), + FUNCTION(blsp11_i2c_scl_b), + FUNCTION(blsp11_i2c_sda_b), + FUNCTION(blsp11_uart_rx_b), + FUNCTION(blsp11_uart_tx_b), + FUNCTION(cam_mclk0), + FUNCTION(cam_mclk1), + FUNCTION(cam_mclk2), + FUNCTION(cam_mclk3), + FUNCTION(cci_async_in0), + FUNCTION(cci_async_in1), + FUNCTION(cci_async_in2), + FUNCTION(cci_i2c0), + FUNCTION(cci_i2c1), + FUNCTION(cci_timer0), + FUNCTION(cci_timer1), + FUNCTION(cci_timer2), + FUNCTION(cci_timer3), + FUNCTION(cci_timer4), + FUNCTION(gcc_gp1_clk_a), + FUNCTION(gcc_gp1_clk_b), + FUNCTION(gcc_gp2_clk_a), + FUNCTION(gcc_gp2_clk_b), + FUNCTION(gcc_gp3_clk_a), + FUNCTION(gcc_gp3_clk_b), + FUNCTION(gp_mn), + FUNCTION(gp_pdm0), + FUNCTION(gp_pdm1), + FUNCTION(gp_pdm2), + FUNCTION(gp0_clk), + FUNCTION(gp1_clk), + FUNCTION(gps_tx), + FUNCTION(gsm_tx), + FUNCTION(hdmi_cec), + FUNCTION(hdmi_ddc), + FUNCTION(hdmi_hpd), + FUNCTION(hdmi_rcv), + FUNCTION(mdp_vsync), + FUNCTION(mss_lte), + FUNCTION(nav_pps), + FUNCTION(nav_tsync), + FUNCTION(qdss_cti_trig_in_a), + FUNCTION(qdss_cti_trig_in_b), + FUNCTION(qdss_cti_trig_in_c), + FUNCTION(qdss_cti_trig_in_d), + FUNCTION(qdss_cti_trig_out_a), + FUNCTION(qdss_cti_trig_out_b), + FUNCTION(qdss_cti_trig_out_c), + FUNCTION(qdss_cti_trig_out_d), + FUNCTION(qdss_traceclk_a), + FUNCTION(qdss_traceclk_b), + FUNCTION(qdss_tracectl_a), + FUNCTION(qdss_tracectl_b), + FUNCTION(qdss_tracedata_a), + FUNCTION(qdss_tracedata_b), + FUNCTION(qua_mi2s), + FUNCTION(pci_e0), + FUNCTION(pci_e1), + FUNCTION(pri_mi2s), + FUNCTION(sdc4), + FUNCTION(sec_mi2s), + FUNCTION(slimbus), + FUNCTION(spkr_i2s), + FUNCTION(ter_mi2s), + FUNCTION(tsif1), + FUNCTION(tsif2), + FUNCTION(uim_batt_alarm), + FUNCTION(uim1), + FUNCTION(uim2), + FUNCTION(uim3), + FUNCTION(uim4), + FUNCTION(gpio), +}; + +static const struct msm_pingroup msm8994_groups[] = { + PINGROUP(0, blsp_spi1, blsp_uart1, blsp_uim1, hdmi_rcv, NA, NA, NA, + NA, NA, NA, NA), + PINGROUP(1, blsp_spi1, blsp_uart1, blsp_uim1, NA, NA, NA, NA, NA, NA, + NA, NA), + PINGROUP(2, blsp_spi1, blsp_uart1, blsp_i2c1, NA, NA, NA, NA, NA, NA, + NA, NA), + PINGROUP(3, blsp_spi1, blsp_uart1, blsp_i2c1, NA, NA, NA, NA, NA, NA, + NA, NA), + PINGROUP(4, blsp_spi2, blsp_uart2, blsp_uim2, NA, qdss_cti_trig_out_b, + NA, NA, NA, NA, NA, NA), + PINGROUP(5, blsp_spi2, blsp_uart2, blsp_uim2, NA, qdss_cti_trig_in_b, + NA, NA, NA, NA, NA, NA), + PINGROUP(6, blsp_spi2, blsp_uart2, blsp_i2c2, NA, NA, NA, NA, NA, NA, + NA, NA), + PINGROUP(7, blsp_spi2, blsp_uart2, blsp_i2c2, NA, NA, NA, NA, NA, NA, + NA, NA), + PINGROUP(8, blsp_spi3, blsp_uart3, blsp_uim3, blsp_spi1_cs1, NA, NA, + NA, NA, NA, NA, NA), + PINGROUP(9, blsp_spi3, blsp_uart3, blsp_uim3, blsp_spi1_cs2, NA, NA, + NA, NA, NA, NA, NA), + PINGROUP(10, mdp_vsync, blsp_spi3, blsp_uart3, blsp_i2c3, + blsp_spi1_cs3, NA, NA, NA, NA, NA, NA), + PINGROUP(11, mdp_vsync, blsp_spi3, blsp_uart3, blsp_i2c3, + blsp_spi1_cs2, NA, NA, NA, NA, NA, NA), + PINGROUP(12, mdp_vsync, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(13, cam_mclk0, NA, NA, qdss_tracedata_b, NA, NA, NA, NA, NA, + NA, NA), + PINGROUP(14, cam_mclk1, NA, NA, qdss_tracedata_b, NA, NA, NA, NA, NA, + NA, NA), + PINGROUP(15, cam_mclk2, NA, qdss_tracedata_b, NA, NA, NA, NA, NA, NA, + NA, NA), + PINGROUP(16, cam_mclk3, NA, qdss_tracedata_b, NA, NA, NA, NA, NA, NA, + NA, NA), + PINGROUP(17, cci_i2c0, blsp_spi4, blsp_uart4, blsp_uim4, NA, + qdss_tracedata_b, NA, NA, NA, NA, NA), + PINGROUP(18, cci_i2c0, blsp_spi4, blsp_uart4, blsp_uim4, NA, + qdss_tracedata_b, NA, NA, NA, NA, NA), + PINGROUP(19, cci_i2c1, blsp_spi4, blsp_uart4, blsp_i2c4, NA, + qdss_tracedata_b, NA, NA, NA, NA, NA), + PINGROUP(20, cci_i2c1, blsp_spi4, blsp_uart4, blsp_i2c4, NA, NA, NA, + NA, NA, NA, NA), + PINGROUP(21, cci_timer0, blsp_spi5, blsp_uart5, blsp_uim5, NA, + qdss_tracedata_b, NA, NA, NA, NA, NA), + PINGROUP(22, cci_timer1, blsp_spi5, blsp_uart5, blsp_uim5, NA, + qdss_tracedata_b, NA, NA, NA, NA, NA), + PINGROUP(23, cci_timer2, blsp_spi5, blsp_uart5, blsp_i2c5, NA, NA, + qdss_tracedata_b, NA, NA, NA, NA), + PINGROUP(24, cci_timer3, cci_async_in1, blsp_spi5, blsp_uart5, + blsp_i2c5, NA, NA, NA, NA, NA, NA), + PINGROUP(25, cci_timer4, cci_async_in2, blsp_spi6, blsp_uart6, + blsp_uim6, NA, NA, qdss_tracedata_b, NA, NA, NA), + PINGROUP(26, cci_async_in0, blsp_spi6, blsp_uart6, blsp_uim6, gp0_clk, + NA, qdss_tracedata_b, NA, NA, NA, NA), + PINGROUP(27, blsp_spi6, blsp_uart6, blsp_i2c6, gp1_clk, + qdss_tracectl_a, NA, NA, NA, NA, NA, NA), + PINGROUP(28, blsp_spi6, blsp_uart6, blsp_i2c6, qdss_traceclk_a, NA, + NA, NA, NA, NA, NA, NA), + PINGROUP(29, gp_mn, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(30, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(31, hdmi_cec, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(32, hdmi_ddc, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(33, hdmi_ddc, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(34, hdmi_hpd, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(35, uim3, pci_e1, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(36, uim3, pci_e1, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(37, uim3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(38, uim3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(39, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(40, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(41, blsp_spi7, blsp_uart7, blsp_uim7, qdss_cti_trig_out_c, + NA, NA, NA, NA, NA, NA, NA), + PINGROUP(42, blsp_spi7, blsp_uart7, blsp_uim7, qdss_cti_trig_in_c, NA, + NA, NA, NA, NA, NA, NA), + PINGROUP(43, blsp_spi7, blsp_uart7, blsp_i2c7, NA, NA, NA, NA, NA, NA, + NA, NA), + PINGROUP(44, blsp_spi7, blsp_uart7, blsp_i2c7, NA, NA, NA, NA, NA, NA, + NA, NA), + PINGROUP(45, blsp_spi8, blsp_uart8, blsp_uim8, NA, NA, NA, NA, NA, NA, + NA, NA), + PINGROUP(46, blsp_spi8, blsp_uart8, blsp_uim8, NA, NA, NA, NA, NA, NA, + NA, NA), + PINGROUP(47, blsp_spi8, blsp_uart8, blsp_i2c8, blsp_spi10_cs1, NA, NA, + NA, NA, NA, NA, NA), + PINGROUP(48, blsp_spi8, blsp_uart8, blsp_i2c8, blsp_spi10_cs2, NA, NA, + NA, NA, NA, NA, NA), + PINGROUP(49, uim2, blsp_spi9, blsp_uart9, blsp_uim9, NA, NA, NA, NA, + NA, NA, NA), + PINGROUP(50, uim2, blsp_spi9, blsp_uart9, blsp_uim9, NA, NA, NA, NA, + NA, NA, NA), + PINGROUP(51, uim2, blsp_spi9, blsp_uart9, blsp_i2c9, NA, NA, NA, NA, + NA, NA, NA), + PINGROUP(52, uim2, blsp_spi9, blsp_uart9, blsp_i2c9, NA, NA, NA, NA, + NA, NA, NA), + PINGROUP(53, uim4, pci_e0, blsp_spi10, blsp_uart10, blsp_uim10, NA, + NA, qdss_tracedata_a, NA, NA, NA), + PINGROUP(54, uim4, pci_e0, blsp_spi10, blsp_uart10, blsp_uim10, + gp_pdm0, NA, NA, qdss_tracedata_a, NA, NA), + PINGROUP(55, uim4, blsp_spi10, blsp_uart10, blsp_i2c10, NA, NA, NA, + qdss_cti_trig_in_a, NA, NA, NA), + PINGROUP(56, uim4, blsp_spi10, blsp_uart10, blsp_i2c10, NA, NA, + qdss_cti_trig_out_a, NA, NA, NA, NA), + PINGROUP(57, qua_mi2s, gcc_gp1_clk_a, NA, NA, qdss_tracedata_b, NA, NA, + NA, NA, NA, NA), + PINGROUP(58, qua_mi2s, gcc_gp2_clk_a, NA, NA, qdss_tracedata_b, NA, NA, + NA, NA, NA, NA), + PINGROUP(59, qua_mi2s, gcc_gp3_clk_a, NA, NA, NA, NA, NA, NA, NA, NA, + NA), + PINGROUP(60, qua_mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(61, qua_mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(62, qua_mi2s, blsp_spi2_cs1, NA, NA, NA, NA, NA, NA, NA, NA, + NA), + PINGROUP(63, qua_mi2s, blsp_spi2_cs2, gp_pdm2, NA, NA, NA, NA, NA, + qdss_tracedata_a, NA, NA), + PINGROUP(64, pri_mi2s, NA, NA, NA, qdss_tracedata_a, NA, NA, NA, NA, + NA, NA), + PINGROUP(65, pri_mi2s, NA, NA, NA, qdss_tracedata_a, NA, NA, NA, NA, + NA, NA), + PINGROUP(66, pri_mi2s, blsp_spi2_cs3, NA, NA, NA, qdss_tracedata_a, + NA, NA, NA, NA, NA), + PINGROUP(67, pri_mi2s, blsp_spi10_cs1, NA, NA, NA, qdss_tracedata_a, + NA, NA, NA, NA, NA), + PINGROUP(68, pri_mi2s, blsp_spi10_cs2, NA, NA, NA, NA, NA, NA, NA, NA, + NA), + PINGROUP(69, spkr_i2s, audio_ref_clk, NA, NA, NA, NA, NA, NA, NA, NA, + NA), + PINGROUP(70, slimbus, spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(71, slimbus, spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(72, spkr_i2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(73, ter_mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(74, ter_mi2s, gp_pdm1, NA, NA, NA, qdss_tracedata_a, NA, NA, + NA, NA, NA), + PINGROUP(75, ter_mi2s, NA, NA, qdss_tracedata_a, NA, NA, NA, NA, NA, + NA, NA), + PINGROUP(76, ter_mi2s, NA, NA, qdss_tracedata_a, NA, NA, NA, NA, NA, + NA, NA), + PINGROUP(77, ter_mi2s, NA, NA, qdss_tracedata_a, NA, NA, NA, NA, NA, + NA, NA), + PINGROUP(78, sec_mi2s, gcc_gp1_clk_b, NA, NA, NA, NA, NA, NA, NA, NA, + NA), + PINGROUP(79, sec_mi2s, gp_pdm2, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(80, sec_mi2s, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(81, sec_mi2s, blsp_spi11, blsp_uart11, blsp_uim11, + gcc_gp2_clk_b, NA, NA, NA, NA, NA, NA), + PINGROUP(82, sec_mi2s, blsp_spi11, blsp_uart11, blsp_uim11, + gcc_gp3_clk_b, NA, NA, NA, NA, NA, NA), + PINGROUP(83, blsp_spi11, blsp_uart11, blsp_i2c11, NA, NA, NA, NA, NA, + NA, NA, NA), + PINGROUP(84, blsp_spi11, blsp_uart11, blsp_i2c11, NA, NA, NA, NA, NA, + NA, NA, NA), + PINGROUP(85, blsp_spi12, blsp_uart12, blsp_uim12, NA, NA, + qdss_tracedata_a, NA, NA, NA, NA, NA), + PINGROUP(86, blsp_spi12, blsp_uart12, blsp_uim12, gp_pdm1, NA, + qdss_tracedata_a, NA, NA, NA, NA, NA), + PINGROUP(87, blsp_spi12, blsp_uart12, blsp_i2c12, NA, + qdss_tracedata_a, NA, NA, NA, NA, NA, NA), + PINGROUP(88, blsp_spi12, blsp_uart12, blsp_i2c12, NA, NA, NA, NA, NA, + NA, NA, NA), + PINGROUP(89, tsif1, NA, qdss_tracedata_a, NA, NA, NA, NA, NA, NA, NA, + NA), + PINGROUP(90, tsif1, blsp_spi10_cs3, qdss_tracedata_a, NA, NA, NA, NA, + NA, NA, NA, NA), + PINGROUP(91, tsif1, sdc4, NA, NA, NA, NA, qdss_traceclk_b, NA, NA, NA, + NA), + PINGROUP(92, tsif2, sdc4, NA, NA, qdss_tracedata_b, NA, NA, NA, NA, + NA, NA), + PINGROUP(93, tsif2, sdc4, NA, NA, NA, NA, qdss_tracedata_b, NA, NA, + NA, NA), + PINGROUP(94, tsif2, sdc4, NA, NA, NA, NA, qdss_tracectl_b, NA, NA, NA, + NA), + PINGROUP(95, tsif2, sdc4, gp_pdm0, NA, NA, NA, qdss_cti_trig_out_d, + NA, NA, NA, NA), + PINGROUP(96, tsif2, sdc4, qdss_cti_trig_in_d, NA, NA, NA, NA, NA, NA, + NA, NA), + PINGROUP(97, uim1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(98, uim1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(99, uim1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(100, uim1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(101, uim_batt_alarm, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(102, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(103, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(104, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(105, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(106, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(107, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(108, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(109, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(110, tsif1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(111, tsif1, blsp11_uart_tx_b, NA, NA, NA, NA, NA, NA, NA, NA, + NA), + PINGROUP(112, blsp11_uart_rx_b, NA, NA, NA, NA, NA, NA, NA, NA, NA, + NA), + PINGROUP(113, blsp11_i2c_sda_b, NA, NA, NA, NA, NA, NA, NA, NA, NA, + NA), + PINGROUP(114, blsp11_i2c_scl_b, NA, NA, NA, NA, NA, NA, NA, NA, NA, + NA), + PINGROUP(115, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(116, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(117, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(118, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(119, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(120, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(121, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(122, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(123, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(124, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(125, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(126, NA, gsm_tx, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(127, NA, nav_tsync, nav_pps, NA, NA, NA, NA, NA, NA, NA, + NA), + PINGROUP(128, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(129, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(130, gps_tx, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(131, gsm_tx, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(132, gsm_tx, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(133, gsm_tx, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(134, mss_lte, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(135, mss_lte, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(136, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(137, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(138, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(139, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(140, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(141, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(142, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(143, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(144, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(145, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + SDC_PINGROUP(sdc1_rclk, 0x2044, 15, 0), + SDC_PINGROUP(sdc1_clk, 0x2044, 13, 6), + SDC_PINGROUP(sdc1_cmd, 0x2044, 11, 3), + SDC_PINGROUP(sdc1_data, 0x2044, 9, 0), + SDC_PINGROUP(sdc2_clk, 0x2048, 14, 6), + SDC_PINGROUP(sdc2_cmd, 0x2048, 11, 3), + SDC_PINGROUP(sdc2_data, 0x2048, 9, 0), + SDC_PINGROUP(sdc3_clk, 0x206c, 14, 6), + SDC_PINGROUP(sdc3_cmd, 0x206c, 11, 3), + SDC_PINGROUP(sdc3_data, 0x206c, 9, 0), +}; + +#define NUM_GPIO_PINGROUPS 146 + +static const struct msm_pinctrl_soc_data msm8994_pinctrl = { + .pins = msm8994_pins, + .npins = ARRAY_SIZE(msm8994_pins), + .functions = msm8994_functions, + .nfunctions = ARRAY_SIZE(msm8994_functions), + .groups = msm8994_groups, + .ngroups = ARRAY_SIZE(msm8994_groups), + .ngpios = NUM_GPIO_PINGROUPS, +}; + +static int msm8994_pinctrl_probe(struct platform_device *pdev) +{ + return msm_pinctrl_probe(pdev, &msm8994_pinctrl); +} + +static const struct of_device_id msm8994_pinctrl_of_match[] = { + { .compatible = "qcom,msm8992-pinctrl", }, + { .compatible = "qcom,msm8994-pinctrl", }, + { } +}; + +static struct platform_driver msm8994_pinctrl_driver = { + .driver = { + .name = "msm8994-pinctrl", + .of_match_table = msm8994_pinctrl_of_match, + }, + .probe = msm8994_pinctrl_probe, + .remove = msm_pinctrl_remove, +}; + +static int __init msm8994_pinctrl_init(void) +{ + return platform_driver_register(&msm8994_pinctrl_driver); +} +arch_initcall(msm8994_pinctrl_init); + +static void __exit msm8994_pinctrl_exit(void) +{ + platform_driver_unregister(&msm8994_pinctrl_driver); +} +module_exit(msm8994_pinctrl_exit); + +MODULE_DESCRIPTION("Qualcomm MSM8994 pinctrl driver"); +MODULE_LICENSE("GPL v2"); +MODULE_DEVICE_TABLE(of, msm8994_pinctrl_of_match); diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index d32fa2b5ff82..12f7d1eb65bc 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -61,16 +61,15 @@ static void exynos_irq_mask(struct irq_data *irqd) struct irq_chip *chip = irq_data_get_irq_chip(irqd); struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); - struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset; unsigned long mask; unsigned long flags; spin_lock_irqsave(&bank->slock, flags); - mask = readl(d->virt_base + reg_mask); + mask = readl(bank->eint_base + reg_mask); mask |= 1 << irqd->hwirq; - writel(mask, d->virt_base + reg_mask); + writel(mask, bank->eint_base + reg_mask); spin_unlock_irqrestore(&bank->slock, flags); } @@ -80,10 +79,9 @@ static void exynos_irq_ack(struct irq_data *irqd) struct irq_chip *chip = irq_data_get_irq_chip(irqd); struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); - struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned long reg_pend = our_chip->eint_pend + bank->eint_offset; - writel(1 << irqd->hwirq, d->virt_base + reg_pend); + writel(1 << irqd->hwirq, bank->eint_base + reg_pend); } static void exynos_irq_unmask(struct irq_data *irqd) @@ -91,7 +89,6 @@ static void exynos_irq_unmask(struct irq_data *irqd) struct irq_chip *chip = irq_data_get_irq_chip(irqd); struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); - struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset; unsigned long mask; unsigned long flags; @@ -109,9 +106,9 @@ static void exynos_irq_unmask(struct irq_data *irqd) spin_lock_irqsave(&bank->slock, flags); - mask = readl(d->virt_base + reg_mask); + mask = readl(bank->eint_base + reg_mask); mask &= ~(1 << irqd->hwirq); - writel(mask, d->virt_base + reg_mask); + writel(mask, bank->eint_base + reg_mask); spin_unlock_irqrestore(&bank->slock, flags); } @@ -121,7 +118,6 @@ static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type) struct irq_chip *chip = irq_data_get_irq_chip(irqd); struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); - struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq; unsigned int con, trig_type; unsigned long reg_con = our_chip->eint_con + bank->eint_offset; @@ -152,10 +148,10 @@ static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type) else irq_set_handler_locked(irqd, handle_level_irq); - con = readl(d->virt_base + reg_con); + con = readl(bank->eint_base + reg_con); con &= ~(EXYNOS_EINT_CON_MASK << shift); con |= trig_type << shift; - writel(con, d->virt_base + reg_con); + writel(con, bank->eint_base + reg_con); return 0; } @@ -166,7 +162,6 @@ static int exynos_irq_request_resources(struct irq_data *irqd) struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); const struct samsung_pin_bank_type *bank_type = bank->type; - struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq; unsigned long reg_con = our_chip->eint_con + bank->eint_offset; unsigned long flags; @@ -188,10 +183,10 @@ static int exynos_irq_request_resources(struct irq_data *irqd) spin_lock_irqsave(&bank->slock, flags); - con = readl(d->virt_base + reg_con); + con = readl(bank->eint_base + reg_con); con &= ~(mask << shift); con |= EXYNOS_EINT_FUNC << shift; - writel(con, d->virt_base + reg_con); + writel(con, bank->eint_base + reg_con); spin_unlock_irqrestore(&bank->slock, flags); @@ -206,7 +201,6 @@ static void exynos_irq_release_resources(struct irq_data *irqd) struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); const struct samsung_pin_bank_type *bank_type = bank->type; - struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq; unsigned long reg_con = our_chip->eint_con + bank->eint_offset; unsigned long flags; @@ -221,10 +215,10 @@ static void exynos_irq_release_resources(struct irq_data *irqd) spin_lock_irqsave(&bank->slock, flags); - con = readl(d->virt_base + reg_con); + con = readl(bank->eint_base + reg_con); con &= ~(mask << shift); con |= FUNC_INPUT << shift; - writel(con, d->virt_base + reg_con); + writel(con, bank->eint_base + reg_con); spin_unlock_irqrestore(&bank->slock, flags); @@ -274,7 +268,7 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data) struct samsung_pin_bank *bank = d->pin_banks; unsigned int svc, group, pin, virq; - svc = readl(d->virt_base + EXYNOS_SVC_OFFSET); + svc = readl(bank->eint_base + EXYNOS_SVC_OFFSET); group = EXYNOS_SVC_GROUP(svc); pin = svc & EXYNOS_SVC_NUM_MASK; @@ -452,7 +446,6 @@ static void exynos_irq_demux_eint16_31(struct irq_desc *desc) { struct irq_chip *chip = irq_desc_get_chip(desc); struct exynos_muxed_weint_data *eintd = irq_desc_get_handler_data(desc); - struct samsung_pinctrl_drv_data *d = eintd->banks[0]->drvdata; unsigned long pend; unsigned long mask; int i; @@ -461,9 +454,9 @@ static void exynos_irq_demux_eint16_31(struct irq_desc *desc) for (i = 0; i < eintd->nr_banks; ++i) { struct samsung_pin_bank *b = eintd->banks[i]; - pend = readl(d->virt_base + b->irq_chip->eint_pend + pend = readl(b->eint_base + b->irq_chip->eint_pend + b->eint_offset); - mask = readl(d->virt_base + b->irq_chip->eint_mask + mask = readl(b->eint_base + b->irq_chip->eint_mask + b->eint_offset); exynos_irq_demux_eint(pend & ~mask, b->irq_domain); } @@ -581,7 +574,7 @@ static void exynos_pinctrl_suspend_bank( struct samsung_pin_bank *bank) { struct exynos_eint_gpio_save *save = bank->soc_priv; - void __iomem *regs = drvdata->virt_base; + void __iomem *regs = bank->eint_base; save->eint_con = readl(regs + EXYNOS_GPIO_ECON_OFFSET + bank->eint_offset); @@ -610,7 +603,7 @@ static void exynos_pinctrl_resume_bank( struct samsung_pin_bank *bank) { struct exynos_eint_gpio_save *save = bank->soc_priv; - void __iomem *regs = drvdata->virt_base; + void __iomem *regs = bank->eint_base; pr_debug("%s: con %#010x => %#010x\n", bank->name, readl(regs + EXYNOS_GPIO_ECON_OFFSET @@ -1346,6 +1339,11 @@ static const struct samsung_pin_bank_data exynos5433_pin_banks0[] = { EXYNOS_PIN_BANK_EINTW(8, 0x020, "gpa1", 0x04), EXYNOS_PIN_BANK_EINTW(8, 0x040, "gpa2", 0x08), EXYNOS_PIN_BANK_EINTW(8, 0x060, "gpa3", 0x0c), + EXYNOS_PIN_BANK_EINTW_EXT(8, 0x020, "gpf1", 0x1004, 1), + EXYNOS_PIN_BANK_EINTW_EXT(4, 0x040, "gpf2", 0x1008, 1), + EXYNOS_PIN_BANK_EINTW_EXT(4, 0x060, "gpf3", 0x100c, 1), + EXYNOS_PIN_BANK_EINTW_EXT(8, 0x080, "gpf4", 0x1010, 1), + EXYNOS_PIN_BANK_EINTW_EXT(8, 0x0a0, "gpf5", 0x1014, 1), }; /* pin banks of exynos5433 pin-controller - AUD */ @@ -1427,6 +1425,7 @@ const struct samsung_pin_ctrl exynos5433_pin_ctrl[] = { .eint_wkup_init = exynos_eint_wkup_init, .suspend = exynos_pinctrl_suspend, .resume = exynos_pinctrl_resume, + .nr_ext_resources = 1, }, { /* pin-controller instance 1 data */ .pin_banks = exynos5433_pin_banks1, diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.h b/drivers/pinctrl/samsung/pinctrl-exynos.h index 0f0f7cedb2dc..5821525a2c84 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.h +++ b/drivers/pinctrl/samsung/pinctrl-exynos.h @@ -79,6 +79,17 @@ .name = id \ } +#define EXYNOS_PIN_BANK_EINTW_EXT(pins, reg, id, offs, pctl_idx) \ + { \ + .type = &bank_type_alive, \ + .pctl_offset = reg, \ + .nr_pins = pins, \ + .eint_type = EINT_TYPE_WKUP, \ + .eint_offset = offs, \ + .name = id, \ + .pctl_res_idx = pctl_idx, \ + } \ + /** * struct exynos_weint_data: irq specific data for all the wakeup interrupts * generated by the external wakeup interrupt controller. diff --git a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c index 3d92f827da7a..b82a003546ae 100644 --- a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c +++ b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c @@ -151,7 +151,7 @@ static void s3c24xx_eint_set_function(struct samsung_pinctrl_drv_data *d, u32 val; /* Make sure that pin is configured as interrupt */ - reg = d->virt_base + bank->pctl_offset; + reg = bank->pctl_base + bank->pctl_offset; shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC]; mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1; @@ -184,7 +184,7 @@ static int s3c24xx_eint_type(struct irq_data *data, unsigned int type) s3c24xx_eint_set_handler(data, type); /* Set up interrupt trigger */ - reg = d->virt_base + EINT_REG(index); + reg = bank->eint_base + EINT_REG(index); shift = EINT_OFFS(index); val = readl(reg); @@ -259,32 +259,29 @@ static void s3c2410_demux_eint0_3(struct irq_desc *desc) static void s3c2412_eint0_3_ack(struct irq_data *data) { struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); - struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned long bitval = 1UL << data->hwirq; - writel(bitval, d->virt_base + EINTPEND_REG); + writel(bitval, bank->eint_base + EINTPEND_REG); } static void s3c2412_eint0_3_mask(struct irq_data *data) { struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); - struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned long mask; - mask = readl(d->virt_base + EINTMASK_REG); + mask = readl(bank->eint_base + EINTMASK_REG); mask |= (1UL << data->hwirq); - writel(mask, d->virt_base + EINTMASK_REG); + writel(mask, bank->eint_base + EINTMASK_REG); } static void s3c2412_eint0_3_unmask(struct irq_data *data) { struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); - struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned long mask; - mask = readl(d->virt_base + EINTMASK_REG); + mask = readl(bank->eint_base + EINTMASK_REG); mask &= ~(1UL << data->hwirq); - writel(mask, d->virt_base + EINTMASK_REG); + writel(mask, bank->eint_base + EINTMASK_REG); } static struct irq_chip s3c2412_eint0_3_chip = { @@ -319,34 +316,31 @@ static void s3c2412_demux_eint0_3(struct irq_desc *desc) static void s3c24xx_eint_ack(struct irq_data *data) { struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); - struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned char index = bank->eint_offset + data->hwirq; - writel(1UL << index, d->virt_base + EINTPEND_REG); + writel(1UL << index, bank->eint_base + EINTPEND_REG); } static void s3c24xx_eint_mask(struct irq_data *data) { struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); - struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned char index = bank->eint_offset + data->hwirq; unsigned long mask; - mask = readl(d->virt_base + EINTMASK_REG); + mask = readl(bank->eint_base + EINTMASK_REG); mask |= (1UL << index); - writel(mask, d->virt_base + EINTMASK_REG); + writel(mask, bank->eint_base + EINTMASK_REG); } static void s3c24xx_eint_unmask(struct irq_data *data) { struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); - struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned char index = bank->eint_offset + data->hwirq; unsigned long mask; - mask = readl(d->virt_base + EINTMASK_REG); + mask = readl(bank->eint_base + EINTMASK_REG); mask &= ~(1UL << index); - writel(mask, d->virt_base + EINTMASK_REG); + writel(mask, bank->eint_base + EINTMASK_REG); } static struct irq_chip s3c24xx_eint_chip = { @@ -362,13 +356,14 @@ static inline void s3c24xx_demux_eint(struct irq_desc *desc, { struct s3c24xx_eint_data *data = irq_desc_get_handler_data(desc); struct irq_chip *chip = irq_desc_get_chip(desc); - struct samsung_pinctrl_drv_data *d = data->drvdata; + struct irq_data *irqd = irq_desc_get_irq_data(desc); + struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); unsigned int pend, mask; chained_irq_enter(chip, desc); - pend = readl(d->virt_base + EINTPEND_REG); - mask = readl(d->virt_base + EINTMASK_REG); + pend = readl(bank->eint_base + EINTPEND_REG); + mask = readl(bank->eint_base + EINTMASK_REG); pend &= ~mask; pend &= range; diff --git a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c index 43407ab248f5..4c632812ccff 100644 --- a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c +++ b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c @@ -280,7 +280,7 @@ static void s3c64xx_irq_set_function(struct samsung_pinctrl_drv_data *d, u32 val; /* Make sure that pin is configured as interrupt */ - reg = d->virt_base + bank->pctl_offset; + reg = bank->pctl_base + bank->pctl_offset; shift = pin; if (bank_type->fld_width[PINCFG_TYPE_FUNC] * shift >= 32) { /* 4-bit bank type with 2 con regs */ @@ -308,9 +308,8 @@ static void s3c64xx_irq_set_function(struct samsung_pinctrl_drv_data *d, static inline void s3c64xx_gpio_irq_set_mask(struct irq_data *irqd, bool mask) { struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); - struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq; - void __iomem *reg = d->virt_base + EINTMASK_REG(bank->eint_offset); + void __iomem *reg = bank->eint_base + EINTMASK_REG(bank->eint_offset); u32 val; val = readl(reg); @@ -334,9 +333,8 @@ static void s3c64xx_gpio_irq_mask(struct irq_data *irqd) static void s3c64xx_gpio_irq_ack(struct irq_data *irqd) { struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); - struct samsung_pinctrl_drv_data *d = bank->drvdata; unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq; - void __iomem *reg = d->virt_base + EINTPEND_REG(bank->eint_offset); + void __iomem *reg = bank->eint_base + EINTPEND_REG(bank->eint_offset); writel(1 << index, reg); } @@ -359,7 +357,7 @@ static int s3c64xx_gpio_irq_set_type(struct irq_data *irqd, unsigned int type) s3c64xx_irq_set_handler(irqd, type); /* Set up interrupt trigger */ - reg = d->virt_base + EINTCON_REG(bank->eint_offset); + reg = bank->eint_base + EINTCON_REG(bank->eint_offset); shift = EINT_OFFS(bank->eint_offset) + irqd->hwirq; shift = 4 * (shift / 4); /* 4 EINTs per trigger selector */ @@ -411,7 +409,8 @@ static void s3c64xx_eint_gpio_irq(struct irq_desc *desc) { struct irq_chip *chip = irq_desc_get_chip(desc); struct s3c64xx_eint_gpio_data *data = irq_desc_get_handler_data(desc); - struct samsung_pinctrl_drv_data *drvdata = data->drvdata; + struct irq_data *irqd = irq_desc_get_irq_data(desc); + struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); chained_irq_enter(chip, desc); @@ -421,7 +420,7 @@ static void s3c64xx_eint_gpio_irq(struct irq_desc *desc) unsigned int pin; unsigned int virq; - svc = readl(drvdata->virt_base + SERVICE_REG); + svc = readl(bank->eint_base + SERVICE_REG); group = SVC_GROUP(svc); pin = svc & SVC_NUM_MASK; @@ -518,15 +517,15 @@ static inline void s3c64xx_eint0_irq_set_mask(struct irq_data *irqd, bool mask) { struct s3c64xx_eint0_domain_data *ddata = irq_data_get_irq_chip_data(irqd); - struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata; + struct samsung_pin_bank *bank = ddata->bank; u32 val; - val = readl(d->virt_base + EINT0MASK_REG); + val = readl(bank->eint_base + EINT0MASK_REG); if (mask) val |= 1 << ddata->eints[irqd->hwirq]; else val &= ~(1 << ddata->eints[irqd->hwirq]); - writel(val, d->virt_base + EINT0MASK_REG); + writel(val, bank->eint_base + EINT0MASK_REG); } static void s3c64xx_eint0_irq_unmask(struct irq_data *irqd) @@ -543,10 +542,10 @@ static void s3c64xx_eint0_irq_ack(struct irq_data *irqd) { struct s3c64xx_eint0_domain_data *ddata = irq_data_get_irq_chip_data(irqd); - struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata; + struct samsung_pin_bank *bank = ddata->bank; writel(1 << ddata->eints[irqd->hwirq], - d->virt_base + EINT0PEND_REG); + bank->eint_base + EINT0PEND_REG); } static int s3c64xx_eint0_irq_set_type(struct irq_data *irqd, unsigned int type) @@ -554,7 +553,7 @@ static int s3c64xx_eint0_irq_set_type(struct irq_data *irqd, unsigned int type) struct s3c64xx_eint0_domain_data *ddata = irq_data_get_irq_chip_data(irqd); struct samsung_pin_bank *bank = ddata->bank; - struct samsung_pinctrl_drv_data *d = bank->drvdata; + struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata; void __iomem *reg; int trigger; u8 shift; @@ -569,7 +568,7 @@ static int s3c64xx_eint0_irq_set_type(struct irq_data *irqd, unsigned int type) s3c64xx_irq_set_handler(irqd, type); /* Set up interrupt trigger */ - reg = d->virt_base + EINT0CON0_REG; + reg = bank->eint_base + EINT0CON0_REG; shift = ddata->eints[irqd->hwirq]; if (shift >= EINT_MAX_PER_REG) { reg += 4; @@ -601,14 +600,19 @@ static struct irq_chip s3c64xx_eint0_irq_chip = { static inline void s3c64xx_irq_demux_eint(struct irq_desc *desc, u32 range) { struct irq_chip *chip = irq_desc_get_chip(desc); + struct irq_data *irqd = irq_desc_get_irq_data(desc); + struct s3c64xx_eint0_domain_data *ddata = + irq_data_get_irq_chip_data(irqd); + struct samsung_pin_bank *bank = ddata->bank; + struct s3c64xx_eint0_data *data = irq_desc_get_handler_data(desc); - struct samsung_pinctrl_drv_data *drvdata = data->drvdata; + unsigned int pend, mask; chained_irq_enter(chip, desc); - pend = readl(drvdata->virt_base + EINT0PEND_REG); - mask = readl(drvdata->virt_base + EINT0MASK_REG); + pend = readl(bank->eint_base + EINT0PEND_REG); + mask = readl(bank->eint_base + EINT0MASK_REG); pend = pend & range & ~mask; pend &= range; diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index 620727fabe64..41e62391c33c 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -33,6 +33,9 @@ #include "../core.h" #include "pinctrl-samsung.h" +/* maximum number of the memory resources */ +#define SAMSUNG_PINCTRL_NUM_RESOURCES 2 + /* list of all possible config options supported */ static struct pin_config { const char *property; @@ -345,7 +348,7 @@ static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata, ((b->pin_base + b->nr_pins - 1) < pin)) b++; - *reg = drvdata->virt_base + b->pctl_offset; + *reg = b->pctl_base + b->pctl_offset; *offset = pin - b->pin_base; if (bank) *bank = b; @@ -526,7 +529,7 @@ static void samsung_gpio_set_value(struct gpio_chip *gc, void __iomem *reg; u32 data; - reg = bank->drvdata->virt_base + bank->pctl_offset; + reg = bank->pctl_base + bank->pctl_offset; data = readl(reg + type->reg_offset[PINCFG_TYPE_DAT]); data &= ~(1 << offset); @@ -554,7 +557,7 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset) struct samsung_pin_bank *bank = gpiochip_get_data(gc); const struct samsung_pin_bank_type *type = bank->type; - reg = bank->drvdata->virt_base + bank->pctl_offset; + reg = bank->pctl_base + bank->pctl_offset; data = readl(reg + type->reg_offset[PINCFG_TYPE_DAT]); data >>= offset; @@ -581,8 +584,8 @@ static int samsung_gpio_set_direction(struct gpio_chip *gc, type = bank->type; drvdata = bank->drvdata; - reg = drvdata->virt_base + bank->pctl_offset + - type->reg_offset[PINCFG_TYPE_FUNC]; + reg = bank->pctl_base + bank->pctl_offset + + type->reg_offset[PINCFG_TYPE_FUNC]; mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1; shift = offset * type->fld_width[PINCFG_TYPE_FUNC]; @@ -979,6 +982,8 @@ samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d, const struct samsung_pin_bank_data *bdata; const struct samsung_pin_ctrl *ctrl; struct samsung_pin_bank *bank; + struct resource *res; + void __iomem *virt_base[SAMSUNG_PINCTRL_NUM_RESOURCES]; int i; id = of_alias_get_id(node, "pinctrl"); @@ -997,6 +1002,17 @@ samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d, if (!d->pin_banks) return ERR_PTR(-ENOMEM); + if (ctrl->nr_ext_resources + 1 > SAMSUNG_PINCTRL_NUM_RESOURCES) + return ERR_PTR(-EINVAL); + + for (i = 0; i < ctrl->nr_ext_resources + 1; i++) { + res = platform_get_resource(pdev, IORESOURCE_MEM, i); + virt_base[i] = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); + if (IS_ERR(virt_base[i])) + return ERR_PTR(-EIO); + } + bank = d->pin_banks; bdata = ctrl->pin_banks; for (i = 0; i < ctrl->nr_banks; ++i, ++bdata, ++bank) { @@ -1013,6 +1029,9 @@ samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d, bank->drvdata = d; bank->pin_base = d->nr_pins; d->nr_pins += bank->nr_pins; + + bank->eint_base = virt_base[0]; + bank->pctl_base = virt_base[bdata->pctl_res_idx]; } for_each_child_of_node(node, np) { @@ -1052,11 +1071,6 @@ static int samsung_pinctrl_probe(struct platform_device *pdev) } drvdata->dev = dev; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - drvdata->virt_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(drvdata->virt_base)) - return PTR_ERR(drvdata->virt_base); - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res) drvdata->irq = res->start; @@ -1094,12 +1108,11 @@ static int samsung_pinctrl_probe(struct platform_device *pdev) static void samsung_pinctrl_suspend_dev( struct samsung_pinctrl_drv_data *drvdata) { - void __iomem *virt_base = drvdata->virt_base; int i; for (i = 0; i < drvdata->nr_banks; i++) { struct samsung_pin_bank *bank = &drvdata->pin_banks[i]; - void __iomem *reg = virt_base + bank->pctl_offset; + void __iomem *reg = bank->pctl_base + bank->pctl_offset; const u8 *offs = bank->type->reg_offset; const u8 *widths = bank->type->fld_width; enum pincfg_type type; @@ -1140,7 +1153,6 @@ static void samsung_pinctrl_suspend_dev( */ static void samsung_pinctrl_resume_dev(struct samsung_pinctrl_drv_data *drvdata) { - void __iomem *virt_base = drvdata->virt_base; int i; if (drvdata->resume) @@ -1148,7 +1160,7 @@ static void samsung_pinctrl_resume_dev(struct samsung_pinctrl_drv_data *drvdata) for (i = 0; i < drvdata->nr_banks; i++) { struct samsung_pin_bank *bank = &drvdata->pin_banks[i]; - void __iomem *reg = virt_base + bank->pctl_offset; + void __iomem *reg = bank->pctl_base + bank->pctl_offset; const u8 *offs = bank->type->reg_offset; const u8 *widths = bank->type->fld_width; enum pincfg_type type; diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h index cd31bfaf62cb..043cb6c11180 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.h +++ b/drivers/pinctrl/samsung/pinctrl-samsung.h @@ -116,6 +116,7 @@ struct samsung_pin_bank_type { * struct samsung_pin_bank_data: represent a controller pin-bank (init data). * @type: type of the bank (register offsets and bitfield widths) * @pctl_offset: starting offset of the pin-bank registers. + * @pctl_res_idx: index of base address for pin-bank registers. * @nr_pins: number of pins included in this bank. * @eint_func: function to set in CON register to configure pin as EINT. * @eint_type: type of the external interrupt supported by the bank. @@ -126,6 +127,7 @@ struct samsung_pin_bank_type { struct samsung_pin_bank_data { const struct samsung_pin_bank_type *type; u32 pctl_offset; + u8 pctl_res_idx; u8 nr_pins; u8 eint_func; enum eint_type eint_type; @@ -137,8 +139,10 @@ struct samsung_pin_bank_data { /** * struct samsung_pin_bank: represent a controller pin-bank. * @type: type of the bank (register offsets and bitfield widths) + * @pctl_base: base address of the pin-bank registers * @pctl_offset: starting offset of the pin-bank registers. * @nr_pins: number of pins included in this bank. + * @eint_base: base address of the pin-bank EINT registers. * @eint_func: function to set in CON register to configure pin as EINT. * @eint_type: type of the external interrupt supported by the bank. * @eint_mask: bit mask of pins which support EINT function. @@ -157,8 +161,10 @@ struct samsung_pin_bank_data { */ struct samsung_pin_bank { const struct samsung_pin_bank_type *type; + void __iomem *pctl_base; u32 pctl_offset; u8 nr_pins; + void __iomem *eint_base; u8 eint_func; enum eint_type eint_type; u32 eint_mask; @@ -182,6 +188,7 @@ struct samsung_pin_bank { * struct samsung_pin_ctrl: represent a pin controller. * @pin_banks: list of pin banks included in this controller. * @nr_banks: number of pin banks. + * @nr_ext_resources: number of the extra base address for pin banks. * @eint_gpio_init: platform specific callback to setup the external gpio * interrupts for the controller. * @eint_wkup_init: platform specific callback to setup the external wakeup @@ -190,6 +197,7 @@ struct samsung_pin_bank { struct samsung_pin_ctrl { const struct samsung_pin_bank_data *pin_banks; u32 nr_banks; + int nr_ext_resources; int (*eint_gpio_init)(struct samsung_pinctrl_drv_data *); int (*eint_wkup_init)(struct samsung_pinctrl_drv_data *); @@ -200,7 +208,6 @@ struct samsung_pin_ctrl { /** * struct samsung_pinctrl_drv_data: wrapper for holding driver data together. * @node: global list node - * @virt_base: register base address of the controller. * @dev: device instance representing the controller. * @irq: interrpt number used by the controller to notify gpio interrupts. * @ctrl: pin controller instance managed by the driver. @@ -215,7 +222,6 @@ struct samsung_pin_ctrl { */ struct samsung_pinctrl_drv_data { struct list_head node; - void __iomem *virt_base; struct device *dev; int irq; diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index f3a8897d4e8f..cf80ce1dd7ce 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -389,6 +389,21 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type) return 0; } +const struct sh_pfc_bias_info * +sh_pfc_pin_to_bias_info(const struct sh_pfc_bias_info *info, + unsigned int num, unsigned int pin) +{ + unsigned int i; + + for (i = 0; i < num; i++) + if (info[i].pin == pin) + return &info[i]; + + WARN_ONCE(1, "Pin %u is not in bias info list\n", pin); + + return NULL; +} + static int sh_pfc_init_ranges(struct sh_pfc *pfc) { struct sh_pfc_pin_range *range; diff --git a/drivers/pinctrl/sh-pfc/core.h b/drivers/pinctrl/sh-pfc/core.h index 0bbdea5849f4..6d598dd63720 100644 --- a/drivers/pinctrl/sh-pfc/core.h +++ b/drivers/pinctrl/sh-pfc/core.h @@ -33,4 +33,8 @@ void sh_pfc_write_reg(struct sh_pfc *pfc, u32 reg, unsigned int width, int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin); int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type); +const struct sh_pfc_bias_info * +sh_pfc_pin_to_bias_info(const struct sh_pfc_bias_info *info, + unsigned int num, unsigned int pin); + #endif /* __SH_PFC_CORE_H__ */ diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7778.c b/drivers/pinctrl/sh-pfc/pfc-r8a7778.c index 18ef7042b3d1..c3af9ebee4af 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7778.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7778.c @@ -24,6 +24,7 @@ #include <linux/kernel.h> #include <linux/pinctrl/pinconf-generic.h> +#include "core.h" #include "sh_pfc.h" #define PORT_GP_PUP_1(bank, pin, fn, sfx) \ @@ -2918,183 +2919,182 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = { #define PUPR4 0x110 #define PUPR5 0x114 -static const struct { - u16 reg : 11; - u16 bit : 5; -} pullups[] = { - [RCAR_GP_PIN(0, 6)] = { PUPR0, 0 }, /* A0 */ - [RCAR_GP_PIN(0, 7)] = { PUPR0, 1 }, /* A1 */ - [RCAR_GP_PIN(0, 8)] = { PUPR0, 2 }, /* A2 */ - [RCAR_GP_PIN(0, 9)] = { PUPR0, 3 }, /* A3 */ - [RCAR_GP_PIN(0, 10)] = { PUPR0, 4 }, /* A4 */ - [RCAR_GP_PIN(0, 11)] = { PUPR0, 5 }, /* A5 */ - [RCAR_GP_PIN(0, 12)] = { PUPR0, 6 }, /* A6 */ - [RCAR_GP_PIN(0, 13)] = { PUPR0, 7 }, /* A7 */ - [RCAR_GP_PIN(0, 14)] = { PUPR0, 8 }, /* A8 */ - [RCAR_GP_PIN(0, 15)] = { PUPR0, 9 }, /* A9 */ - [RCAR_GP_PIN(0, 16)] = { PUPR0, 10 }, /* A10 */ - [RCAR_GP_PIN(0, 17)] = { PUPR0, 11 }, /* A11 */ - [RCAR_GP_PIN(0, 18)] = { PUPR0, 12 }, /* A12 */ - [RCAR_GP_PIN(0, 19)] = { PUPR0, 13 }, /* A13 */ - [RCAR_GP_PIN(0, 20)] = { PUPR0, 14 }, /* A14 */ - [RCAR_GP_PIN(0, 21)] = { PUPR0, 15 }, /* A15 */ - [RCAR_GP_PIN(0, 22)] = { PUPR0, 16 }, /* A16 */ - [RCAR_GP_PIN(0, 23)] = { PUPR0, 17 }, /* A17 */ - [RCAR_GP_PIN(0, 24)] = { PUPR0, 18 }, /* A18 */ - [RCAR_GP_PIN(0, 25)] = { PUPR0, 19 }, /* A19 */ - [RCAR_GP_PIN(0, 26)] = { PUPR0, 20 }, /* A20 */ - [RCAR_GP_PIN(0, 27)] = { PUPR0, 21 }, /* A21 */ - [RCAR_GP_PIN(0, 28)] = { PUPR0, 22 }, /* A22 */ - [RCAR_GP_PIN(0, 29)] = { PUPR0, 23 }, /* A23 */ - [RCAR_GP_PIN(0, 30)] = { PUPR0, 24 }, /* A24 */ - [RCAR_GP_PIN(0, 31)] = { PUPR0, 25 }, /* A25 */ - [RCAR_GP_PIN(1, 3)] = { PUPR0, 26 }, /* /EX_CS0 */ - [RCAR_GP_PIN(1, 4)] = { PUPR0, 27 }, /* /EX_CS1 */ - [RCAR_GP_PIN(1, 5)] = { PUPR0, 28 }, /* /EX_CS2 */ - [RCAR_GP_PIN(1, 6)] = { PUPR0, 29 }, /* /EX_CS3 */ - [RCAR_GP_PIN(1, 7)] = { PUPR0, 30 }, /* /EX_CS4 */ - [RCAR_GP_PIN(1, 8)] = { PUPR0, 31 }, /* /EX_CS5 */ - - [RCAR_GP_PIN(0, 0)] = { PUPR1, 0 }, /* /PRESETOUT */ - [RCAR_GP_PIN(0, 5)] = { PUPR1, 1 }, /* /BS */ - [RCAR_GP_PIN(1, 0)] = { PUPR1, 2 }, /* RD//WR */ - [RCAR_GP_PIN(1, 1)] = { PUPR1, 3 }, /* /WE0 */ - [RCAR_GP_PIN(1, 2)] = { PUPR1, 4 }, /* /WE1 */ - [RCAR_GP_PIN(1, 11)] = { PUPR1, 5 }, /* EX_WAIT0 */ - [RCAR_GP_PIN(1, 9)] = { PUPR1, 6 }, /* DREQ0 */ - [RCAR_GP_PIN(1, 10)] = { PUPR1, 7 }, /* DACK0 */ - [RCAR_GP_PIN(1, 12)] = { PUPR1, 8 }, /* IRQ0 */ - [RCAR_GP_PIN(1, 13)] = { PUPR1, 9 }, /* IRQ1 */ - - [RCAR_GP_PIN(1, 22)] = { PUPR2, 0 }, /* DU0_DR0 */ - [RCAR_GP_PIN(1, 23)] = { PUPR2, 1 }, /* DU0_DR1 */ - [RCAR_GP_PIN(1, 24)] = { PUPR2, 2 }, /* DU0_DR2 */ - [RCAR_GP_PIN(1, 25)] = { PUPR2, 3 }, /* DU0_DR3 */ - [RCAR_GP_PIN(1, 26)] = { PUPR2, 4 }, /* DU0_DR4 */ - [RCAR_GP_PIN(1, 27)] = { PUPR2, 5 }, /* DU0_DR5 */ - [RCAR_GP_PIN(1, 28)] = { PUPR2, 6 }, /* DU0_DR6 */ - [RCAR_GP_PIN(1, 29)] = { PUPR2, 7 }, /* DU0_DR7 */ - [RCAR_GP_PIN(1, 30)] = { PUPR2, 8 }, /* DU0_DG0 */ - [RCAR_GP_PIN(1, 31)] = { PUPR2, 9 }, /* DU0_DG1 */ - [RCAR_GP_PIN(2, 0)] = { PUPR2, 10 }, /* DU0_DG2 */ - [RCAR_GP_PIN(2, 1)] = { PUPR2, 11 }, /* DU0_DG3 */ - [RCAR_GP_PIN(2, 2)] = { PUPR2, 12 }, /* DU0_DG4 */ - [RCAR_GP_PIN(2, 3)] = { PUPR2, 13 }, /* DU0_DG5 */ - [RCAR_GP_PIN(2, 4)] = { PUPR2, 14 }, /* DU0_DG6 */ - [RCAR_GP_PIN(2, 5)] = { PUPR2, 15 }, /* DU0_DG7 */ - [RCAR_GP_PIN(2, 6)] = { PUPR2, 16 }, /* DU0_DB0 */ - [RCAR_GP_PIN(2, 7)] = { PUPR2, 17 }, /* DU0_DB1 */ - [RCAR_GP_PIN(2, 8)] = { PUPR2, 18 }, /* DU0_DB2 */ - [RCAR_GP_PIN(2, 9)] = { PUPR2, 19 }, /* DU0_DB3 */ - [RCAR_GP_PIN(2, 10)] = { PUPR2, 20 }, /* DU0_DB4 */ - [RCAR_GP_PIN(2, 11)] = { PUPR2, 21 }, /* DU0_DB5 */ - [RCAR_GP_PIN(2, 12)] = { PUPR2, 22 }, /* DU0_DB6 */ - [RCAR_GP_PIN(2, 13)] = { PUPR2, 23 }, /* DU0_DB7 */ - [RCAR_GP_PIN(2, 14)] = { PUPR2, 24 }, /* DU0_DOTCLKIN */ - [RCAR_GP_PIN(2, 15)] = { PUPR2, 25 }, /* DU0_DOTCLKOUT0 */ - [RCAR_GP_PIN(2, 17)] = { PUPR2, 26 }, /* DU0_HSYNC */ - [RCAR_GP_PIN(2, 18)] = { PUPR2, 27 }, /* DU0_VSYNC */ - [RCAR_GP_PIN(2, 19)] = { PUPR2, 28 }, /* DU0_EXODDF */ - [RCAR_GP_PIN(2, 20)] = { PUPR2, 29 }, /* DU0_DISP */ - [RCAR_GP_PIN(2, 21)] = { PUPR2, 30 }, /* DU0_CDE */ - [RCAR_GP_PIN(2, 16)] = { PUPR2, 31 }, /* DU0_DOTCLKOUT1 */ - - [RCAR_GP_PIN(3, 24)] = { PUPR3, 0 }, /* VI0_CLK */ - [RCAR_GP_PIN(3, 25)] = { PUPR3, 1 }, /* VI0_CLKENB */ - [RCAR_GP_PIN(3, 26)] = { PUPR3, 2 }, /* VI0_FIELD */ - [RCAR_GP_PIN(3, 27)] = { PUPR3, 3 }, /* /VI0_HSYNC */ - [RCAR_GP_PIN(3, 28)] = { PUPR3, 4 }, /* /VI0_VSYNC */ - [RCAR_GP_PIN(3, 29)] = { PUPR3, 5 }, /* VI0_DATA0 */ - [RCAR_GP_PIN(3, 30)] = { PUPR3, 6 }, /* VI0_DATA1 */ - [RCAR_GP_PIN(3, 31)] = { PUPR3, 7 }, /* VI0_DATA2 */ - [RCAR_GP_PIN(4, 0)] = { PUPR3, 8 }, /* VI0_DATA3 */ - [RCAR_GP_PIN(4, 1)] = { PUPR3, 9 }, /* VI0_DATA4 */ - [RCAR_GP_PIN(4, 2)] = { PUPR3, 10 }, /* VI0_DATA5 */ - [RCAR_GP_PIN(4, 3)] = { PUPR3, 11 }, /* VI0_DATA6 */ - [RCAR_GP_PIN(4, 4)] = { PUPR3, 12 }, /* VI0_DATA7 */ - [RCAR_GP_PIN(4, 5)] = { PUPR3, 13 }, /* VI0_G2 */ - [RCAR_GP_PIN(4, 6)] = { PUPR3, 14 }, /* VI0_G3 */ - [RCAR_GP_PIN(4, 7)] = { PUPR3, 15 }, /* VI0_G4 */ - [RCAR_GP_PIN(4, 8)] = { PUPR3, 16 }, /* VI0_G5 */ - [RCAR_GP_PIN(4, 21)] = { PUPR3, 17 }, /* VI1_DATA12 */ - [RCAR_GP_PIN(4, 22)] = { PUPR3, 18 }, /* VI1_DATA13 */ - [RCAR_GP_PIN(4, 23)] = { PUPR3, 19 }, /* VI1_DATA14 */ - [RCAR_GP_PIN(4, 24)] = { PUPR3, 20 }, /* VI1_DATA15 */ - [RCAR_GP_PIN(4, 9)] = { PUPR3, 21 }, /* ETH_REF_CLK */ - [RCAR_GP_PIN(4, 10)] = { PUPR3, 22 }, /* ETH_TXD0 */ - [RCAR_GP_PIN(4, 11)] = { PUPR3, 23 }, /* ETH_TXD1 */ - [RCAR_GP_PIN(4, 12)] = { PUPR3, 24 }, /* ETH_CRS_DV */ - [RCAR_GP_PIN(4, 13)] = { PUPR3, 25 }, /* ETH_TX_EN */ - [RCAR_GP_PIN(4, 14)] = { PUPR3, 26 }, /* ETH_RX_ER */ - [RCAR_GP_PIN(4, 15)] = { PUPR3, 27 }, /* ETH_RXD0 */ - [RCAR_GP_PIN(4, 16)] = { PUPR3, 28 }, /* ETH_RXD1 */ - [RCAR_GP_PIN(4, 17)] = { PUPR3, 29 }, /* ETH_MDC */ - [RCAR_GP_PIN(4, 18)] = { PUPR3, 30 }, /* ETH_MDIO */ - [RCAR_GP_PIN(4, 19)] = { PUPR3, 31 }, /* ETH_LINK */ - - [RCAR_GP_PIN(3, 6)] = { PUPR4, 0 }, /* SSI_SCK012 */ - [RCAR_GP_PIN(3, 7)] = { PUPR4, 1 }, /* SSI_WS012 */ - [RCAR_GP_PIN(3, 10)] = { PUPR4, 2 }, /* SSI_SDATA0 */ - [RCAR_GP_PIN(3, 9)] = { PUPR4, 3 }, /* SSI_SDATA1 */ - [RCAR_GP_PIN(3, 8)] = { PUPR4, 4 }, /* SSI_SDATA2 */ - [RCAR_GP_PIN(3, 2)] = { PUPR4, 5 }, /* SSI_SCK34 */ - [RCAR_GP_PIN(3, 3)] = { PUPR4, 6 }, /* SSI_WS34 */ - [RCAR_GP_PIN(3, 5)] = { PUPR4, 7 }, /* SSI_SDATA3 */ - [RCAR_GP_PIN(3, 4)] = { PUPR4, 8 }, /* SSI_SDATA4 */ - [RCAR_GP_PIN(2, 31)] = { PUPR4, 9 }, /* SSI_SCK5 */ - [RCAR_GP_PIN(3, 0)] = { PUPR4, 10 }, /* SSI_WS5 */ - [RCAR_GP_PIN(3, 1)] = { PUPR4, 11 }, /* SSI_SDATA5 */ - [RCAR_GP_PIN(2, 28)] = { PUPR4, 12 }, /* SSI_SCK6 */ - [RCAR_GP_PIN(2, 29)] = { PUPR4, 13 }, /* SSI_WS6 */ - [RCAR_GP_PIN(2, 30)] = { PUPR4, 14 }, /* SSI_SDATA6 */ - [RCAR_GP_PIN(2, 24)] = { PUPR4, 15 }, /* SSI_SCK78 */ - [RCAR_GP_PIN(2, 25)] = { PUPR4, 16 }, /* SSI_WS78 */ - [RCAR_GP_PIN(2, 27)] = { PUPR4, 17 }, /* SSI_SDATA7 */ - [RCAR_GP_PIN(2, 26)] = { PUPR4, 18 }, /* SSI_SDATA8 */ - [RCAR_GP_PIN(3, 23)] = { PUPR4, 19 }, /* TCLK0 */ - [RCAR_GP_PIN(3, 11)] = { PUPR4, 20 }, /* SD0_CLK */ - [RCAR_GP_PIN(3, 12)] = { PUPR4, 21 }, /* SD0_CMD */ - [RCAR_GP_PIN(3, 13)] = { PUPR4, 22 }, /* SD0_DAT0 */ - [RCAR_GP_PIN(3, 14)] = { PUPR4, 23 }, /* SD0_DAT1 */ - [RCAR_GP_PIN(3, 15)] = { PUPR4, 24 }, /* SD0_DAT2 */ - [RCAR_GP_PIN(3, 16)] = { PUPR4, 25 }, /* SD0_DAT3 */ - [RCAR_GP_PIN(3, 17)] = { PUPR4, 26 }, /* SD0_CD */ - [RCAR_GP_PIN(3, 18)] = { PUPR4, 27 }, /* SD0_WP */ - [RCAR_GP_PIN(2, 22)] = { PUPR4, 28 }, /* AUDIO_CLKA */ - [RCAR_GP_PIN(2, 23)] = { PUPR4, 29 }, /* AUDIO_CLKB */ - [RCAR_GP_PIN(1, 14)] = { PUPR4, 30 }, /* IRQ2 */ - [RCAR_GP_PIN(1, 15)] = { PUPR4, 31 }, /* IRQ3 */ - - [RCAR_GP_PIN(0, 1)] = { PUPR5, 0 }, /* PENC0 */ - [RCAR_GP_PIN(0, 2)] = { PUPR5, 1 }, /* PENC1 */ - [RCAR_GP_PIN(0, 3)] = { PUPR5, 2 }, /* USB_OVC0 */ - [RCAR_GP_PIN(0, 4)] = { PUPR5, 3 }, /* USB_OVC1 */ - [RCAR_GP_PIN(1, 16)] = { PUPR5, 4 }, /* SCIF_CLK */ - [RCAR_GP_PIN(1, 17)] = { PUPR5, 5 }, /* TX0 */ - [RCAR_GP_PIN(1, 18)] = { PUPR5, 6 }, /* RX0 */ - [RCAR_GP_PIN(1, 19)] = { PUPR5, 7 }, /* SCK0 */ - [RCAR_GP_PIN(1, 20)] = { PUPR5, 8 }, /* /CTS0 */ - [RCAR_GP_PIN(1, 21)] = { PUPR5, 9 }, /* /RTS0 */ - [RCAR_GP_PIN(3, 19)] = { PUPR5, 10 }, /* HSPI_CLK0 */ - [RCAR_GP_PIN(3, 20)] = { PUPR5, 11 }, /* /HSPI_CS0 */ - [RCAR_GP_PIN(3, 21)] = { PUPR5, 12 }, /* HSPI_RX0 */ - [RCAR_GP_PIN(3, 22)] = { PUPR5, 13 }, /* HSPI_TX0 */ - [RCAR_GP_PIN(4, 20)] = { PUPR5, 14 }, /* ETH_MAGIC */ - [RCAR_GP_PIN(4, 25)] = { PUPR5, 15 }, /* AVS1 */ - [RCAR_GP_PIN(4, 26)] = { PUPR5, 16 }, /* AVS2 */ +static const struct sh_pfc_bias_info bias_info[] = { + { RCAR_GP_PIN(0, 6), PUPR0, 0 }, /* A0 */ + { RCAR_GP_PIN(0, 7), PUPR0, 1 }, /* A1 */ + { RCAR_GP_PIN(0, 8), PUPR0, 2 }, /* A2 */ + { RCAR_GP_PIN(0, 9), PUPR0, 3 }, /* A3 */ + { RCAR_GP_PIN(0, 10), PUPR0, 4 }, /* A4 */ + { RCAR_GP_PIN(0, 11), PUPR0, 5 }, /* A5 */ + { RCAR_GP_PIN(0, 12), PUPR0, 6 }, /* A6 */ + { RCAR_GP_PIN(0, 13), PUPR0, 7 }, /* A7 */ + { RCAR_GP_PIN(0, 14), PUPR0, 8 }, /* A8 */ + { RCAR_GP_PIN(0, 15), PUPR0, 9 }, /* A9 */ + { RCAR_GP_PIN(0, 16), PUPR0, 10 }, /* A10 */ + { RCAR_GP_PIN(0, 17), PUPR0, 11 }, /* A11 */ + { RCAR_GP_PIN(0, 18), PUPR0, 12 }, /* A12 */ + { RCAR_GP_PIN(0, 19), PUPR0, 13 }, /* A13 */ + { RCAR_GP_PIN(0, 20), PUPR0, 14 }, /* A14 */ + { RCAR_GP_PIN(0, 21), PUPR0, 15 }, /* A15 */ + { RCAR_GP_PIN(0, 22), PUPR0, 16 }, /* A16 */ + { RCAR_GP_PIN(0, 23), PUPR0, 17 }, /* A17 */ + { RCAR_GP_PIN(0, 24), PUPR0, 18 }, /* A18 */ + { RCAR_GP_PIN(0, 25), PUPR0, 19 }, /* A19 */ + { RCAR_GP_PIN(0, 26), PUPR0, 20 }, /* A20 */ + { RCAR_GP_PIN(0, 27), PUPR0, 21 }, /* A21 */ + { RCAR_GP_PIN(0, 28), PUPR0, 22 }, /* A22 */ + { RCAR_GP_PIN(0, 29), PUPR0, 23 }, /* A23 */ + { RCAR_GP_PIN(0, 30), PUPR0, 24 }, /* A24 */ + { RCAR_GP_PIN(0, 31), PUPR0, 25 }, /* A25 */ + { RCAR_GP_PIN(1, 3), PUPR0, 26 }, /* /EX_CS0 */ + { RCAR_GP_PIN(1, 4), PUPR0, 27 }, /* /EX_CS1 */ + { RCAR_GP_PIN(1, 5), PUPR0, 28 }, /* /EX_CS2 */ + { RCAR_GP_PIN(1, 6), PUPR0, 29 }, /* /EX_CS3 */ + { RCAR_GP_PIN(1, 7), PUPR0, 30 }, /* /EX_CS4 */ + { RCAR_GP_PIN(1, 8), PUPR0, 31 }, /* /EX_CS5 */ + + { RCAR_GP_PIN(0, 0), PUPR1, 0 }, /* /PRESETOUT */ + { RCAR_GP_PIN(0, 5), PUPR1, 1 }, /* /BS */ + { RCAR_GP_PIN(1, 0), PUPR1, 2 }, /* RD//WR */ + { RCAR_GP_PIN(1, 1), PUPR1, 3 }, /* /WE0 */ + { RCAR_GP_PIN(1, 2), PUPR1, 4 }, /* /WE1 */ + { RCAR_GP_PIN(1, 11), PUPR1, 5 }, /* EX_WAIT0 */ + { RCAR_GP_PIN(1, 9), PUPR1, 6 }, /* DREQ0 */ + { RCAR_GP_PIN(1, 10), PUPR1, 7 }, /* DACK0 */ + { RCAR_GP_PIN(1, 12), PUPR1, 8 }, /* IRQ0 */ + { RCAR_GP_PIN(1, 13), PUPR1, 9 }, /* IRQ1 */ + + { RCAR_GP_PIN(1, 22), PUPR2, 0 }, /* DU0_DR0 */ + { RCAR_GP_PIN(1, 23), PUPR2, 1 }, /* DU0_DR1 */ + { RCAR_GP_PIN(1, 24), PUPR2, 2 }, /* DU0_DR2 */ + { RCAR_GP_PIN(1, 25), PUPR2, 3 }, /* DU0_DR3 */ + { RCAR_GP_PIN(1, 26), PUPR2, 4 }, /* DU0_DR4 */ + { RCAR_GP_PIN(1, 27), PUPR2, 5 }, /* DU0_DR5 */ + { RCAR_GP_PIN(1, 28), PUPR2, 6 }, /* DU0_DR6 */ + { RCAR_GP_PIN(1, 29), PUPR2, 7 }, /* DU0_DR7 */ + { RCAR_GP_PIN(1, 30), PUPR2, 8 }, /* DU0_DG0 */ + { RCAR_GP_PIN(1, 31), PUPR2, 9 }, /* DU0_DG1 */ + { RCAR_GP_PIN(2, 0), PUPR2, 10 }, /* DU0_DG2 */ + { RCAR_GP_PIN(2, 1), PUPR2, 11 }, /* DU0_DG3 */ + { RCAR_GP_PIN(2, 2), PUPR2, 12 }, /* DU0_DG4 */ + { RCAR_GP_PIN(2, 3), PUPR2, 13 }, /* DU0_DG5 */ + { RCAR_GP_PIN(2, 4), PUPR2, 14 }, /* DU0_DG6 */ + { RCAR_GP_PIN(2, 5), PUPR2, 15 }, /* DU0_DG7 */ + { RCAR_GP_PIN(2, 6), PUPR2, 16 }, /* DU0_DB0 */ + { RCAR_GP_PIN(2, 7), PUPR2, 17 }, /* DU0_DB1 */ + { RCAR_GP_PIN(2, 8), PUPR2, 18 }, /* DU0_DB2 */ + { RCAR_GP_PIN(2, 9), PUPR2, 19 }, /* DU0_DB3 */ + { RCAR_GP_PIN(2, 10), PUPR2, 20 }, /* DU0_DB4 */ + { RCAR_GP_PIN(2, 11), PUPR2, 21 }, /* DU0_DB5 */ + { RCAR_GP_PIN(2, 12), PUPR2, 22 }, /* DU0_DB6 */ + { RCAR_GP_PIN(2, 13), PUPR2, 23 }, /* DU0_DB7 */ + { RCAR_GP_PIN(2, 14), PUPR2, 24 }, /* DU0_DOTCLKIN */ + { RCAR_GP_PIN(2, 15), PUPR2, 25 }, /* DU0_DOTCLKOUT0 */ + { RCAR_GP_PIN(2, 17), PUPR2, 26 }, /* DU0_HSYNC */ + { RCAR_GP_PIN(2, 18), PUPR2, 27 }, /* DU0_VSYNC */ + { RCAR_GP_PIN(2, 19), PUPR2, 28 }, /* DU0_EXODDF */ + { RCAR_GP_PIN(2, 20), PUPR2, 29 }, /* DU0_DISP */ + { RCAR_GP_PIN(2, 21), PUPR2, 30 }, /* DU0_CDE */ + { RCAR_GP_PIN(2, 16), PUPR2, 31 }, /* DU0_DOTCLKOUT1 */ + + { RCAR_GP_PIN(3, 24), PUPR3, 0 }, /* VI0_CLK */ + { RCAR_GP_PIN(3, 25), PUPR3, 1 }, /* VI0_CLKENB */ + { RCAR_GP_PIN(3, 26), PUPR3, 2 }, /* VI0_FIELD */ + { RCAR_GP_PIN(3, 27), PUPR3, 3 }, /* /VI0_HSYNC */ + { RCAR_GP_PIN(3, 28), PUPR3, 4 }, /* /VI0_VSYNC */ + { RCAR_GP_PIN(3, 29), PUPR3, 5 }, /* VI0_DATA0 */ + { RCAR_GP_PIN(3, 30), PUPR3, 6 }, /* VI0_DATA1 */ + { RCAR_GP_PIN(3, 31), PUPR3, 7 }, /* VI0_DATA2 */ + { RCAR_GP_PIN(4, 0), PUPR3, 8 }, /* VI0_DATA3 */ + { RCAR_GP_PIN(4, 1), PUPR3, 9 }, /* VI0_DATA4 */ + { RCAR_GP_PIN(4, 2), PUPR3, 10 }, /* VI0_DATA5 */ + { RCAR_GP_PIN(4, 3), PUPR3, 11 }, /* VI0_DATA6 */ + { RCAR_GP_PIN(4, 4), PUPR3, 12 }, /* VI0_DATA7 */ + { RCAR_GP_PIN(4, 5), PUPR3, 13 }, /* VI0_G2 */ + { RCAR_GP_PIN(4, 6), PUPR3, 14 }, /* VI0_G3 */ + { RCAR_GP_PIN(4, 7), PUPR3, 15 }, /* VI0_G4 */ + { RCAR_GP_PIN(4, 8), PUPR3, 16 }, /* VI0_G5 */ + { RCAR_GP_PIN(4, 21), PUPR3, 17 }, /* VI1_DATA12 */ + { RCAR_GP_PIN(4, 22), PUPR3, 18 }, /* VI1_DATA13 */ + { RCAR_GP_PIN(4, 23), PUPR3, 19 }, /* VI1_DATA14 */ + { RCAR_GP_PIN(4, 24), PUPR3, 20 }, /* VI1_DATA15 */ + { RCAR_GP_PIN(4, 9), PUPR3, 21 }, /* ETH_REF_CLK */ + { RCAR_GP_PIN(4, 10), PUPR3, 22 }, /* ETH_TXD0 */ + { RCAR_GP_PIN(4, 11), PUPR3, 23 }, /* ETH_TXD1 */ + { RCAR_GP_PIN(4, 12), PUPR3, 24 }, /* ETH_CRS_DV */ + { RCAR_GP_PIN(4, 13), PUPR3, 25 }, /* ETH_TX_EN */ + { RCAR_GP_PIN(4, 14), PUPR3, 26 }, /* ETH_RX_ER */ + { RCAR_GP_PIN(4, 15), PUPR3, 27 }, /* ETH_RXD0 */ + { RCAR_GP_PIN(4, 16), PUPR3, 28 }, /* ETH_RXD1 */ + { RCAR_GP_PIN(4, 17), PUPR3, 29 }, /* ETH_MDC */ + { RCAR_GP_PIN(4, 18), PUPR3, 30 }, /* ETH_MDIO */ + { RCAR_GP_PIN(4, 19), PUPR3, 31 }, /* ETH_LINK */ + + { RCAR_GP_PIN(3, 6), PUPR4, 0 }, /* SSI_SCK012 */ + { RCAR_GP_PIN(3, 7), PUPR4, 1 }, /* SSI_WS012 */ + { RCAR_GP_PIN(3, 10), PUPR4, 2 }, /* SSI_SDATA0 */ + { RCAR_GP_PIN(3, 9), PUPR4, 3 }, /* SSI_SDATA1 */ + { RCAR_GP_PIN(3, 8), PUPR4, 4 }, /* SSI_SDATA2 */ + { RCAR_GP_PIN(3, 2), PUPR4, 5 }, /* SSI_SCK34 */ + { RCAR_GP_PIN(3, 3), PUPR4, 6 }, /* SSI_WS34 */ + { RCAR_GP_PIN(3, 5), PUPR4, 7 }, /* SSI_SDATA3 */ + { RCAR_GP_PIN(3, 4), PUPR4, 8 }, /* SSI_SDATA4 */ + { RCAR_GP_PIN(2, 31), PUPR4, 9 }, /* SSI_SCK5 */ + { RCAR_GP_PIN(3, 0), PUPR4, 10 }, /* SSI_WS5 */ + { RCAR_GP_PIN(3, 1), PUPR4, 11 }, /* SSI_SDATA5 */ + { RCAR_GP_PIN(2, 28), PUPR4, 12 }, /* SSI_SCK6 */ + { RCAR_GP_PIN(2, 29), PUPR4, 13 }, /* SSI_WS6 */ + { RCAR_GP_PIN(2, 30), PUPR4, 14 }, /* SSI_SDATA6 */ + { RCAR_GP_PIN(2, 24), PUPR4, 15 }, /* SSI_SCK78 */ + { RCAR_GP_PIN(2, 25), PUPR4, 16 }, /* SSI_WS78 */ + { RCAR_GP_PIN(2, 27), PUPR4, 17 }, /* SSI_SDATA7 */ + { RCAR_GP_PIN(2, 26), PUPR4, 18 }, /* SSI_SDATA8 */ + { RCAR_GP_PIN(3, 23), PUPR4, 19 }, /* TCLK0 */ + { RCAR_GP_PIN(3, 11), PUPR4, 20 }, /* SD0_CLK */ + { RCAR_GP_PIN(3, 12), PUPR4, 21 }, /* SD0_CMD */ + { RCAR_GP_PIN(3, 13), PUPR4, 22 }, /* SD0_DAT0 */ + { RCAR_GP_PIN(3, 14), PUPR4, 23 }, /* SD0_DAT1 */ + { RCAR_GP_PIN(3, 15), PUPR4, 24 }, /* SD0_DAT2 */ + { RCAR_GP_PIN(3, 16), PUPR4, 25 }, /* SD0_DAT3 */ + { RCAR_GP_PIN(3, 17), PUPR4, 26 }, /* SD0_CD */ + { RCAR_GP_PIN(3, 18), PUPR4, 27 }, /* SD0_WP */ + { RCAR_GP_PIN(2, 22), PUPR4, 28 }, /* AUDIO_CLKA */ + { RCAR_GP_PIN(2, 23), PUPR4, 29 }, /* AUDIO_CLKB */ + { RCAR_GP_PIN(1, 14), PUPR4, 30 }, /* IRQ2 */ + { RCAR_GP_PIN(1, 15), PUPR4, 31 }, /* IRQ3 */ + + { RCAR_GP_PIN(0, 1), PUPR5, 0 }, /* PENC0 */ + { RCAR_GP_PIN(0, 2), PUPR5, 1 }, /* PENC1 */ + { RCAR_GP_PIN(0, 3), PUPR5, 2 }, /* USB_OVC0 */ + { RCAR_GP_PIN(0, 4), PUPR5, 3 }, /* USB_OVC1 */ + { RCAR_GP_PIN(1, 16), PUPR5, 4 }, /* SCIF_CLK */ + { RCAR_GP_PIN(1, 17), PUPR5, 5 }, /* TX0 */ + { RCAR_GP_PIN(1, 18), PUPR5, 6 }, /* RX0 */ + { RCAR_GP_PIN(1, 19), PUPR5, 7 }, /* SCK0 */ + { RCAR_GP_PIN(1, 20), PUPR5, 8 }, /* /CTS0 */ + { RCAR_GP_PIN(1, 21), PUPR5, 9 }, /* /RTS0 */ + { RCAR_GP_PIN(3, 19), PUPR5, 10 }, /* HSPI_CLK0 */ + { RCAR_GP_PIN(3, 20), PUPR5, 11 }, /* /HSPI_CS0 */ + { RCAR_GP_PIN(3, 21), PUPR5, 12 }, /* HSPI_RX0 */ + { RCAR_GP_PIN(3, 22), PUPR5, 13 }, /* HSPI_TX0 */ + { RCAR_GP_PIN(4, 20), PUPR5, 14 }, /* ETH_MAGIC */ + { RCAR_GP_PIN(4, 25), PUPR5, 15 }, /* AVS1 */ + { RCAR_GP_PIN(4, 26), PUPR5, 16 }, /* AVS2 */ }; static unsigned int r8a7778_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin) { + const struct sh_pfc_bias_info *info; void __iomem *addr; - if (WARN_ON_ONCE(!pullups[pin].reg)) + info = sh_pfc_pin_to_bias_info(bias_info, ARRAY_SIZE(bias_info), pin); + if (!info) return PIN_CONFIG_BIAS_DISABLE; - addr = pfc->windows->virt + pullups[pin].reg; + addr = pfc->windows->virt + info->reg; - if (ioread32(addr) & BIT(pullups[pin].bit)) + if (ioread32(addr) & BIT(info->bit)) return PIN_CONFIG_BIAS_PULL_UP; else return PIN_CONFIG_BIAS_DISABLE; @@ -3103,15 +3103,17 @@ static unsigned int r8a7778_pinmux_get_bias(struct sh_pfc *pfc, static void r8a7778_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, unsigned int bias) { + const struct sh_pfc_bias_info *info; void __iomem *addr; u32 value; u32 bit; - if (WARN_ON_ONCE(!pullups[pin].reg)) + info = sh_pfc_pin_to_bias_info(bias_info, ARRAY_SIZE(bias_info), pin); + if (!info) return; - addr = pfc->windows->virt + pullups[pin].reg; - bit = BIT(pullups[pin].bit); + addr = pfc->windows->virt + info->reg; + bit = BIT(info->bit); value = ioread32(addr) & ~bit; if (bias == PIN_CONFIG_BIAS_PULL_UP) diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7795.c b/drivers/pinctrl/sh-pfc/pfc-r8a7795.c index 2e8cc2adbed7..135ed5cbeb44 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7795.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7795.c @@ -523,6 +523,22 @@ MOD_SEL0_2_1 MOD_SEL1_2 \ MOD_SEL1_1 \ MOD_SEL1_0 MOD_SEL2_0 +/* + * These pins are not able to be muxed but have other properties + * that can be set, such as drive-strength or pull-up/pull-down enable. + */ +#define PINMUX_STATIC \ + FM(QSPI0_SPCLK) FM(QSPI0_SSL) FM(QSPI0_MOSI_IO0) FM(QSPI0_MISO_IO1) \ + FM(QSPI0_IO2) FM(QSPI0_IO3) \ + FM(QSPI1_SPCLK) FM(QSPI1_SSL) FM(QSPI1_MOSI_IO0) FM(QSPI1_MISO_IO1) \ + FM(QSPI1_IO2) FM(QSPI1_IO3) \ + FM(RPC_INT) FM(RPC_WP) FM(RPC_RESET) \ + FM(AVB_TX_CTL) FM(AVB_TXC) FM(AVB_TD0) FM(AVB_TD1) FM(AVB_TD2) FM(AVB_TD3) \ + FM(AVB_RX_CTL) FM(AVB_RXC) FM(AVB_RD0) FM(AVB_RD1) FM(AVB_RD2) FM(AVB_RD3) \ + FM(AVB_TXCREFCLK) FM(AVB_MDIO) \ + FM(CLKOUT) FM(PRESETOUT) \ + FM(DU_DOTCLKIN0) FM(DU_DOTCLKIN1) FM(DU_DOTCLKIN2) FM(DU_DOTCLKIN3) \ + FM(TMS) FM(TDO) FM(ASEBRK) FM(MLB_REF) enum { PINMUX_RESERVED = 0, @@ -548,6 +564,7 @@ enum { PINMUX_GPSR PINMUX_IPSR PINMUX_MOD_SELS + PINMUX_STATIC PINMUX_MARK_END, #undef F_ #undef FM @@ -1412,10 +1429,78 @@ static const u16 pinmux_data[] = { PINMUX_IPSR_MSEL(IP17_7_4, STP_ISSYNC_0_E, SEL_SSP1_0_4), PINMUX_IPSR_MSEL(IP17_7_4, RIF2_D1_B, SEL_DRIF2_1), PINMUX_IPSR_GPSR(IP17_7_4, TPU0TO3), + +/* + * Static pins can not be muxed between different functions but + * still needs a mark entry in the pinmux list. Add each static + * pin to the list without an associated function. The sh-pfc + * core will do the right thing and skip trying to mux then pin + * while still applying configuration to it + */ +#define FM(x) PINMUX_DATA(x##_MARK, 0), + PINMUX_STATIC +#undef FM }; +/* + * R8A7795 has 8 banks with 32 PGIOS in each => 256 GPIOs. + * Physical layout rows: A - AW, cols: 1 - 39. + */ +#define ROW_GROUP_A(r) ('Z' - 'A' + 1 + (r)) +#define PIN_NUMBER(r, c) (((r) - 'A') * 39 + (c) + 300) +#define PIN_A_NUMBER(r, c) PIN_NUMBER(ROW_GROUP_A(r), c) + static const struct sh_pfc_pin pinmux_pins[] = { PINMUX_GPIO_GP_ALL(), + + /* + * Pins not associated with a GPIO port. + * + * The pin positions are different between different r8a7795 + * packages, all that is needed for the pfc driver is a unique + * number for each pin. To this end use the pin layout from + * R-Car H3SiP to calculate a unique number for each pin. + */ + SH_PFC_PIN_NAMED_CFG('A', 8, AVB_TX_CTL, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG('A', 9, AVB_MDIO, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG('A', 12, AVB_TXCREFCLK, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG('A', 13, AVB_RD0, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG('A', 14, AVB_RD2, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG('A', 16, AVB_RX_CTL, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG('A', 17, AVB_TD2, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG('A', 18, AVB_TD0, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG('A', 19, AVB_TXC, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG('B', 13, AVB_RD1, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG('B', 14, AVB_RD3, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG('B', 17, AVB_TD3, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG('B', 18, AVB_TD1, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG('B', 19, AVB_RXC, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG('C', 1, PRESETOUT#, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG('F', 1, CLKOUT, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG('H', 37, MLB_REF, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG('V', 3, QSPI1_SPCLK, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG('V', 5, QSPI1_SSL, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG('V', 6, RPC_WP#, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG('V', 7, RPC_RESET#, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG('W', 3, QSPI0_SPCLK, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG('Y', 3, QSPI0_SSL, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG('Y', 6, QSPI0_IO2, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG('Y', 7, RPC_INT#, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('B'), 4, QSPI0_MISO_IO1, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('B'), 6, QSPI0_IO3, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('C'), 3, QSPI1_IO3, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('C'), 5, QSPI0_MOSI_IO0, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('C'), 7, QSPI1_MOSI_IO0, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('D'), 38, FSCLKST#, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('E'), 4, QSPI1_IO2, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('E'), 5, QSPI1_MISO_IO1, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('P'), 7, DU_DOTCLKIN0, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('P'), 8, DU_DOTCLKIN1, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('R'), 7, DU_DOTCLKIN2, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('R'), 8, DU_DOTCLKIN3, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('R'), 30, TMS, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('T'), 28, TDO, SH_PFC_PIN_CFG_DRIVE_STRENGTH), + SH_PFC_PIN_NAMED_CFG(ROW_GROUP_A('T'), 30, ASEBRK, SH_PFC_PIN_CFG_DRIVE_STRENGTH), }; /* - AUDIO CLOCK ------------------------------------------------------------ */ @@ -1563,11 +1648,33 @@ static const unsigned int avb_phy_int_mux[] = { AVB_PHY_INT_MARK, }; static const unsigned int avb_mdc_pins[] = { - /* AVB_MDC */ - RCAR_GP_PIN(2, 9), + /* AVB_MDC, AVB_MDIO */ + RCAR_GP_PIN(2, 9), PIN_NUMBER('A', 9), }; static const unsigned int avb_mdc_mux[] = { - AVB_MDC_MARK, + AVB_MDC_MARK, AVB_MDIO_MARK, +}; +static const unsigned int avb_mii_pins[] = { + /* + * AVB_TX_CTL, AVB_TXC, AVB_TD0, + * AVB_TD1, AVB_TD2, AVB_TD3, + * AVB_RX_CTL, AVB_RXC, AVB_RD0, + * AVB_RD1, AVB_RD2, AVB_RD3, + * AVB_TXCREFCLK + */ + PIN_NUMBER('A', 8), PIN_NUMBER('A', 19), PIN_NUMBER('A', 18), + PIN_NUMBER('B', 18), PIN_NUMBER('A', 17), PIN_NUMBER('B', 17), + PIN_NUMBER('A', 16), PIN_NUMBER('B', 19), PIN_NUMBER('A', 13), + PIN_NUMBER('B', 13), PIN_NUMBER('A', 14), PIN_NUMBER('B', 14), + PIN_NUMBER('A', 12), + +}; +static const unsigned int avb_mii_mux[] = { + AVB_TX_CTL_MARK, AVB_TXC_MARK, AVB_TD0_MARK, + AVB_TD1_MARK, AVB_TD2_MARK, AVB_TD3_MARK, + AVB_RX_CTL_MARK, AVB_RXC_MARK, AVB_RD0_MARK, + AVB_RD1_MARK, AVB_RD2_MARK, AVB_RD3_MARK, + AVB_TXCREFCLK_MARK, }; static const unsigned int avb_avtp_pps_pins[] = { /* AVB_AVTP_PPS */ @@ -3613,6 +3720,55 @@ static const unsigned int usb2_mux[] = { USB2_PWEN_MARK, USB2_OVC_MARK, }; +/* - QSPI0 ------------------------------------------------------------------ */ +static const unsigned int qspi0_ctrl_pins[] = { + /* QSPI0_SPCLK, QSPI0_SSL */ + PIN_NUMBER('W', 3), PIN_NUMBER('Y', 3), +}; +static const unsigned int qspi0_ctrl_mux[] = { + QSPI0_SPCLK_MARK, QSPI0_SSL_MARK, +}; +static const unsigned int qspi0_data2_pins[] = { + /* QSPI0_MOSI_IO0, QSPI0_MISO_IO1 */ + PIN_A_NUMBER('C', 5), PIN_A_NUMBER('B', 4), +}; +static const unsigned int qspi0_data2_mux[] = { + QSPI0_MOSI_IO0_MARK, QSPI0_MISO_IO1_MARK, +}; +static const unsigned int qspi0_data4_pins[] = { + /* QSPI0_MOSI_IO0, QSPI0_MISO_IO1, QSPI0_IO2, QSPI0_IO3 */ + PIN_A_NUMBER('C', 5), PIN_A_NUMBER('B', 4), + PIN_NUMBER('Y', 6), PIN_A_NUMBER('B', 6), +}; +static const unsigned int qspi0_data4_mux[] = { + QSPI0_MOSI_IO0_MARK, QSPI0_MISO_IO1_MARK, + QSPI0_IO2_MARK, QSPI0_IO3_MARK, +}; +/* - QSPI1 ------------------------------------------------------------------ */ +static const unsigned int qspi1_ctrl_pins[] = { + /* QSPI1_SPCLK, QSPI1_SSL */ + PIN_NUMBER('V', 3), PIN_NUMBER('V', 5), +}; +static const unsigned int qspi1_ctrl_mux[] = { + QSPI1_SPCLK_MARK, QSPI1_SSL_MARK, +}; +static const unsigned int qspi1_data2_pins[] = { + /* QSPI1_MOSI_IO0, QSPI1_MISO_IO1 */ + PIN_A_NUMBER('C', 7), PIN_A_NUMBER('E', 5), +}; +static const unsigned int qspi1_data2_mux[] = { + QSPI1_MOSI_IO0_MARK, QSPI1_MISO_IO1_MARK, +}; +static const unsigned int qspi1_data4_pins[] = { + /* QSPI1_MOSI_IO0, QSPI1_MISO_IO1, QSPI1_IO2, QSPI1_IO3 */ + PIN_A_NUMBER('C', 7), PIN_A_NUMBER('E', 5), + PIN_A_NUMBER('E', 4), PIN_A_NUMBER('C', 3), +}; +static const unsigned int qspi1_data4_mux[] = { + QSPI1_MOSI_IO0_MARK, QSPI1_MISO_IO1_MARK, + QSPI1_IO2_MARK, QSPI1_IO3_MARK, +}; + static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(audio_clk_a_a), SH_PFC_PIN_GROUP(audio_clk_a_b), @@ -3635,6 +3791,7 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(avb_magic), SH_PFC_PIN_GROUP(avb_phy_int), SH_PFC_PIN_GROUP(avb_mdc), + SH_PFC_PIN_GROUP(avb_mii), SH_PFC_PIN_GROUP(avb_avtp_pps), SH_PFC_PIN_GROUP(avb_avtp_match_a), SH_PFC_PIN_GROUP(avb_avtp_capture_a), @@ -3912,6 +4069,12 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(usb0), SH_PFC_PIN_GROUP(usb1), SH_PFC_PIN_GROUP(usb2), + SH_PFC_PIN_GROUP(qspi0_ctrl), + SH_PFC_PIN_GROUP(qspi0_data2), + SH_PFC_PIN_GROUP(qspi0_data4), + SH_PFC_PIN_GROUP(qspi1_ctrl), + SH_PFC_PIN_GROUP(qspi1_data2), + SH_PFC_PIN_GROUP(qspi1_data4), }; static const char * const audio_clk_groups[] = { @@ -3939,6 +4102,7 @@ static const char * const avb_groups[] = { "avb_magic", "avb_phy_int", "avb_mdc", + "avb_mii", "avb_avtp_pps", "avb_avtp_match_a", "avb_avtp_capture_a", @@ -4356,6 +4520,18 @@ static const char * const usb2_groups[] = { "usb2", }; +static const char * const qspi0_groups[] = { + "qspi0_ctrl", + "qspi0_data2", + "qspi0_data4", +}; + +static const char * const qspi1_groups[] = { + "qspi1_ctrl", + "qspi1_data2", + "qspi1_data4", +}; + static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(audio_clk), SH_PFC_FUNCTION(avb), @@ -4405,6 +4581,8 @@ static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(usb0), SH_PFC_FUNCTION(usb1), SH_PFC_FUNCTION(usb2), + SH_PFC_FUNCTION(qspi0), + SH_PFC_FUNCTION(qspi1), }; static const struct pinmux_cfg_reg pinmux_config_regs[] = { @@ -4962,10 +5140,45 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = { }; static const struct pinmux_drive_reg pinmux_drive_regs[] = { + { PINMUX_DRIVE_REG("DRVCTRL0", 0xe6060300) { + { PIN_NUMBER('W', 3), 28, 2 }, /* QSPI0_SPCLK */ + { PIN_A_NUMBER('C', 5), 24, 2 }, /* QSPI0_MOSI_IO0 */ + { PIN_A_NUMBER('B', 4), 20, 2 }, /* QSPI0_MISO_IO1 */ + { PIN_NUMBER('Y', 6), 16, 2 }, /* QSPI0_IO2 */ + { PIN_A_NUMBER('B', 6), 12, 2 }, /* QSPI0_IO3 */ + { PIN_NUMBER('Y', 3), 8, 2 }, /* QSPI0_SSL */ + { PIN_NUMBER('V', 3), 4, 2 }, /* QSPI1_SPCLK */ + { PIN_A_NUMBER('C', 7), 0, 2 }, /* QSPI1_MOSI_IO0 */ + } }, + { PINMUX_DRIVE_REG("DRVCTRL1", 0xe6060304) { + { PIN_A_NUMBER('E', 5), 28, 2 }, /* QSPI1_MISO_IO1 */ + { PIN_A_NUMBER('E', 4), 24, 2 }, /* QSPI1_IO2 */ + { PIN_A_NUMBER('C', 3), 20, 2 }, /* QSPI1_IO3 */ + { PIN_NUMBER('V', 5), 16, 2 }, /* QSPI1_SSL */ + { PIN_NUMBER('Y', 7), 12, 2 }, /* RPC_INT# */ + { PIN_NUMBER('V', 6), 8, 2 }, /* RPC_WP# */ + { PIN_NUMBER('V', 7), 4, 2 }, /* RPC_RESET# */ + { PIN_NUMBER('A', 16), 0, 3 }, /* AVB_RX_CTL */ + } }, + { PINMUX_DRIVE_REG("DRVCTRL2", 0xe6060308) { + { PIN_NUMBER('B', 19), 28, 3 }, /* AVB_RXC */ + { PIN_NUMBER('A', 13), 24, 3 }, /* AVB_RD0 */ + { PIN_NUMBER('B', 13), 20, 3 }, /* AVB_RD1 */ + { PIN_NUMBER('A', 14), 16, 3 }, /* AVB_RD2 */ + { PIN_NUMBER('B', 14), 12, 3 }, /* AVB_RD3 */ + { PIN_NUMBER('A', 8), 8, 3 }, /* AVB_TX_CTL */ + { PIN_NUMBER('A', 19), 4, 3 }, /* AVB_TXC */ + { PIN_NUMBER('A', 18), 0, 3 }, /* AVB_TD0 */ + } }, { PINMUX_DRIVE_REG("DRVCTRL3", 0xe606030c) { - { RCAR_GP_PIN(2, 9), 8, 3 }, /* AVB_MDC */ - { RCAR_GP_PIN(2, 10), 4, 3 }, /* AVB_MAGIC */ - { RCAR_GP_PIN(2, 11), 0, 3 }, /* AVB_PHY_INT */ + { PIN_NUMBER('B', 18), 28, 3 }, /* AVB_TD1 */ + { PIN_NUMBER('A', 17), 24, 3 }, /* AVB_TD2 */ + { PIN_NUMBER('B', 17), 20, 3 }, /* AVB_TD3 */ + { PIN_NUMBER('A', 12), 16, 3 }, /* AVB_TXCREFCLK */ + { PIN_NUMBER('A', 9), 12, 3 }, /* AVB_MDIO */ + { RCAR_GP_PIN(2, 9), 8, 3 }, /* AVB_MDC */ + { RCAR_GP_PIN(2, 10), 4, 3 }, /* AVB_MAGIC */ + { RCAR_GP_PIN(2, 11), 0, 3 }, /* AVB_PHY_INT */ } }, { PINMUX_DRIVE_REG("DRVCTRL4", 0xe6060310) { { RCAR_GP_PIN(2, 12), 28, 3 }, /* AVB_LINK */ @@ -5008,6 +5221,7 @@ static const struct pinmux_drive_reg pinmux_drive_regs[] = { { RCAR_GP_PIN(1, 19), 0, 3 }, /* A19 */ } }, { PINMUX_DRIVE_REG("DRVCTRL8", 0xe6060320) { + { PIN_NUMBER('F', 1), 28, 3 }, /* CLKOUT */ { RCAR_GP_PIN(1, 20), 24, 3 }, /* CS0 */ { RCAR_GP_PIN(1, 21), 20, 3 }, /* CS1_A26 */ { RCAR_GP_PIN(1, 22), 16, 3 }, /* BS */ @@ -5018,6 +5232,7 @@ static const struct pinmux_drive_reg pinmux_drive_regs[] = { } }, { PINMUX_DRIVE_REG("DRVCTRL9", 0xe6060324) { { RCAR_GP_PIN(1, 27), 28, 3 }, /* EX_WAIT0 */ + { PIN_NUMBER('C', 1), 24, 3 }, /* PRESETOUT# */ { RCAR_GP_PIN(0, 0), 20, 3 }, /* D0 */ { RCAR_GP_PIN(0, 1), 16, 3 }, /* D1 */ { RCAR_GP_PIN(0, 2), 12, 3 }, /* D2 */ @@ -5036,20 +5251,30 @@ static const struct pinmux_drive_reg pinmux_drive_regs[] = { { RCAR_GP_PIN(0, 13), 0, 3 }, /* D13 */ } }, { PINMUX_DRIVE_REG("DRVCTRL11", 0xe606032c) { - { RCAR_GP_PIN(0, 14), 28, 3 }, /* D14 */ - { RCAR_GP_PIN(0, 15), 24, 3 }, /* D15 */ - { RCAR_GP_PIN(7, 0), 20, 3 }, /* AVS1 */ - { RCAR_GP_PIN(7, 1), 16, 3 }, /* AVS2 */ - { RCAR_GP_PIN(7, 2), 12, 3 }, /* HDMI0_CEC */ - { RCAR_GP_PIN(7, 3), 8, 3 }, /* HDMI1_CEC */ + { RCAR_GP_PIN(0, 14), 28, 3 }, /* D14 */ + { RCAR_GP_PIN(0, 15), 24, 3 }, /* D15 */ + { RCAR_GP_PIN(7, 0), 20, 3 }, /* AVS1 */ + { RCAR_GP_PIN(7, 1), 16, 3 }, /* AVS2 */ + { RCAR_GP_PIN(7, 2), 12, 3 }, /* HDMI0_CEC */ + { RCAR_GP_PIN(7, 3), 8, 3 }, /* HDMI1_CEC */ + { PIN_A_NUMBER('P', 7), 4, 2 }, /* DU_DOTCLKIN0 */ + { PIN_A_NUMBER('P', 8), 0, 2 }, /* DU_DOTCLKIN1 */ + } }, + { PINMUX_DRIVE_REG("DRVCTRL12", 0xe6060330) { + { PIN_A_NUMBER('R', 7), 28, 2 }, /* DU_DOTCLKIN2 */ + { PIN_A_NUMBER('R', 8), 24, 2 }, /* DU_DOTCLKIN3 */ + { PIN_A_NUMBER('D', 38), 20, 2 }, /* FSCLKST# */ + { PIN_A_NUMBER('R', 30), 4, 2 }, /* TMS */ } }, { PINMUX_DRIVE_REG("DRVCTRL13", 0xe6060334) { - { RCAR_GP_PIN(3, 0), 20, 3 }, /* SD0_CLK */ - { RCAR_GP_PIN(3, 1), 16, 3 }, /* SD0_CMD */ - { RCAR_GP_PIN(3, 2), 12, 3 }, /* SD0_DAT0 */ - { RCAR_GP_PIN(3, 3), 8, 3 }, /* SD0_DAT1 */ - { RCAR_GP_PIN(3, 4), 4, 3 }, /* SD0_DAT2 */ - { RCAR_GP_PIN(3, 5), 0, 3 }, /* SD0_DAT3 */ + { PIN_A_NUMBER('T', 28), 28, 2 }, /* TDO */ + { PIN_A_NUMBER('T', 30), 24, 2 }, /* ASEBRK */ + { RCAR_GP_PIN(3, 0), 20, 3 }, /* SD0_CLK */ + { RCAR_GP_PIN(3, 1), 16, 3 }, /* SD0_CMD */ + { RCAR_GP_PIN(3, 2), 12, 3 }, /* SD0_DAT0 */ + { RCAR_GP_PIN(3, 3), 8, 3 }, /* SD0_DAT1 */ + { RCAR_GP_PIN(3, 4), 4, 3 }, /* SD0_DAT2 */ + { RCAR_GP_PIN(3, 5), 0, 3 }, /* SD0_DAT3 */ } }, { PINMUX_DRIVE_REG("DRVCTRL14", 0xe6060338) { { RCAR_GP_PIN(3, 6), 28, 3 }, /* SD1_CLK */ @@ -5118,6 +5343,7 @@ static const struct pinmux_drive_reg pinmux_drive_regs[] = { { RCAR_GP_PIN(5, 23), 16, 3 }, /* MLB_CLK */ { RCAR_GP_PIN(5, 24), 12, 3 }, /* MLB_SIG */ { RCAR_GP_PIN(5, 25), 8, 3 }, /* MLB_DAT */ + { PIN_NUMBER('H', 37), 4, 3 }, /* MLB_REF */ { RCAR_GP_PIN(6, 0), 0, 3 }, /* SSI_SCK01239 */ } }, { PINMUX_DRIVE_REG("DRVCTRL21", 0xe6060354) { @@ -5188,206 +5414,206 @@ static int r8a7795_pin_to_pocctrl(struct sh_pfc *pfc, unsigned int pin, u32 *poc #define PU5 0x14 #define PU6 0x18 -static const struct { - u16 reg : 11; - u16 bit : 5; -} pullups[] = { - [RCAR_GP_PIN(2, 11)] = { PU0, 31 }, /* AVB_PHY_INT */ - [RCAR_GP_PIN(2, 10)] = { PU0, 30 }, /* AVB_MAGIC */ - [RCAR_GP_PIN(2, 9)] = { PU0, 29 }, /* AVB_MDC */ - - [RCAR_GP_PIN(1, 19)] = { PU1, 31 }, /* A19 */ - [RCAR_GP_PIN(1, 18)] = { PU1, 30 }, /* A18 */ - [RCAR_GP_PIN(1, 17)] = { PU1, 29 }, /* A17 */ - [RCAR_GP_PIN(1, 16)] = { PU1, 28 }, /* A16 */ - [RCAR_GP_PIN(1, 15)] = { PU1, 27 }, /* A15 */ - [RCAR_GP_PIN(1, 14)] = { PU1, 26 }, /* A14 */ - [RCAR_GP_PIN(1, 13)] = { PU1, 25 }, /* A13 */ - [RCAR_GP_PIN(1, 12)] = { PU1, 24 }, /* A12 */ - [RCAR_GP_PIN(1, 11)] = { PU1, 23 }, /* A11 */ - [RCAR_GP_PIN(1, 10)] = { PU1, 22 }, /* A10 */ - [RCAR_GP_PIN(1, 9)] = { PU1, 21 }, /* A9 */ - [RCAR_GP_PIN(1, 8)] = { PU1, 20 }, /* A8 */ - [RCAR_GP_PIN(1, 7)] = { PU1, 19 }, /* A7 */ - [RCAR_GP_PIN(1, 6)] = { PU1, 18 }, /* A6 */ - [RCAR_GP_PIN(1, 5)] = { PU1, 17 }, /* A5 */ - [RCAR_GP_PIN(1, 4)] = { PU1, 16 }, /* A4 */ - [RCAR_GP_PIN(1, 3)] = { PU1, 15 }, /* A3 */ - [RCAR_GP_PIN(1, 2)] = { PU1, 14 }, /* A2 */ - [RCAR_GP_PIN(1, 1)] = { PU1, 13 }, /* A1 */ - [RCAR_GP_PIN(1, 0)] = { PU1, 12 }, /* A0 */ - [RCAR_GP_PIN(2, 8)] = { PU1, 11 }, /* PWM2_A */ - [RCAR_GP_PIN(2, 7)] = { PU1, 10 }, /* PWM1_A */ - [RCAR_GP_PIN(2, 6)] = { PU1, 9 }, /* PWM0 */ - [RCAR_GP_PIN(2, 5)] = { PU1, 8 }, /* IRQ5 */ - [RCAR_GP_PIN(2, 4)] = { PU1, 7 }, /* IRQ4 */ - [RCAR_GP_PIN(2, 3)] = { PU1, 6 }, /* IRQ3 */ - [RCAR_GP_PIN(2, 2)] = { PU1, 5 }, /* IRQ2 */ - [RCAR_GP_PIN(2, 1)] = { PU1, 4 }, /* IRQ1 */ - [RCAR_GP_PIN(2, 0)] = { PU1, 3 }, /* IRQ0 */ - [RCAR_GP_PIN(2, 14)] = { PU1, 2 }, /* AVB_AVTP_CAPTURE_A */ - [RCAR_GP_PIN(2, 13)] = { PU1, 1 }, /* AVB_AVTP_MATCH_A */ - [RCAR_GP_PIN(2, 12)] = { PU1, 0 }, /* AVB_LINK */ - - [RCAR_GP_PIN(7, 3)] = { PU2, 29 }, /* HDMI1_CEC */ - [RCAR_GP_PIN(7, 2)] = { PU2, 28 }, /* HDMI0_CEC */ - [RCAR_GP_PIN(7, 1)] = { PU2, 27 }, /* AVS2 */ - [RCAR_GP_PIN(7, 0)] = { PU2, 26 }, /* AVS1 */ - [RCAR_GP_PIN(0, 15)] = { PU2, 25 }, /* D15 */ - [RCAR_GP_PIN(0, 14)] = { PU2, 24 }, /* D14 */ - [RCAR_GP_PIN(0, 13)] = { PU2, 23 }, /* D13 */ - [RCAR_GP_PIN(0, 12)] = { PU2, 22 }, /* D12 */ - [RCAR_GP_PIN(0, 11)] = { PU2, 21 }, /* D11 */ - [RCAR_GP_PIN(0, 10)] = { PU2, 20 }, /* D10 */ - [RCAR_GP_PIN(0, 9)] = { PU2, 19 }, /* D9 */ - [RCAR_GP_PIN(0, 8)] = { PU2, 18 }, /* D8 */ - [RCAR_GP_PIN(0, 7)] = { PU2, 17 }, /* D7 */ - [RCAR_GP_PIN(0, 6)] = { PU2, 16 }, /* D6 */ - [RCAR_GP_PIN(0, 5)] = { PU2, 15 }, /* D5 */ - [RCAR_GP_PIN(0, 4)] = { PU2, 14 }, /* D4 */ - [RCAR_GP_PIN(0, 3)] = { PU2, 13 }, /* D3 */ - [RCAR_GP_PIN(0, 2)] = { PU2, 12 }, /* D2 */ - [RCAR_GP_PIN(0, 1)] = { PU2, 11 }, /* D1 */ - [RCAR_GP_PIN(0, 0)] = { PU2, 10 }, /* D0 */ - [RCAR_GP_PIN(1, 27)] = { PU2, 8 }, /* EX_WAIT0_A */ - [RCAR_GP_PIN(1, 26)] = { PU2, 7 }, /* WE1_N */ - [RCAR_GP_PIN(1, 25)] = { PU2, 6 }, /* WE0_N */ - [RCAR_GP_PIN(1, 24)] = { PU2, 5 }, /* RD_WR_N */ - [RCAR_GP_PIN(1, 23)] = { PU2, 4 }, /* RD_N */ - [RCAR_GP_PIN(1, 22)] = { PU2, 3 }, /* BS_N */ - [RCAR_GP_PIN(1, 21)] = { PU2, 2 }, /* CS1_N_A26 */ - [RCAR_GP_PIN(1, 20)] = { PU2, 1 }, /* CS0_N */ - - [RCAR_GP_PIN(4, 9)] = { PU3, 31 }, /* SD3_DAT0 */ - [RCAR_GP_PIN(4, 8)] = { PU3, 30 }, /* SD3_CMD */ - [RCAR_GP_PIN(4, 7)] = { PU3, 29 }, /* SD3_CLK */ - [RCAR_GP_PIN(4, 6)] = { PU3, 28 }, /* SD2_DS */ - [RCAR_GP_PIN(4, 5)] = { PU3, 27 }, /* SD2_DAT3 */ - [RCAR_GP_PIN(4, 4)] = { PU3, 26 }, /* SD2_DAT2 */ - [RCAR_GP_PIN(4, 3)] = { PU3, 25 }, /* SD2_DAT1 */ - [RCAR_GP_PIN(4, 2)] = { PU3, 24 }, /* SD2_DAT0 */ - [RCAR_GP_PIN(4, 1)] = { PU3, 23 }, /* SD2_CMD */ - [RCAR_GP_PIN(4, 0)] = { PU3, 22 }, /* SD2_CLK */ - [RCAR_GP_PIN(3, 11)] = { PU3, 21 }, /* SD1_DAT3 */ - [RCAR_GP_PIN(3, 10)] = { PU3, 20 }, /* SD1_DAT2 */ - [RCAR_GP_PIN(3, 9)] = { PU3, 19 }, /* SD1_DAT1 */ - [RCAR_GP_PIN(3, 8)] = { PU3, 18 }, /* SD1_DAT0 */ - [RCAR_GP_PIN(3, 7)] = { PU3, 17 }, /* SD1_CMD */ - [RCAR_GP_PIN(3, 6)] = { PU3, 16 }, /* SD1_CLK */ - [RCAR_GP_PIN(3, 5)] = { PU3, 15 }, /* SD0_DAT3 */ - [RCAR_GP_PIN(3, 4)] = { PU3, 14 }, /* SD0_DAT2 */ - [RCAR_GP_PIN(3, 3)] = { PU3, 13 }, /* SD0_DAT1 */ - [RCAR_GP_PIN(3, 2)] = { PU3, 12 }, /* SD0_DAT0 */ - [RCAR_GP_PIN(3, 1)] = { PU3, 11 }, /* SD0_CMD */ - [RCAR_GP_PIN(3, 0)] = { PU3, 10 }, /* SD0_CLK */ - - [RCAR_GP_PIN(5, 19)] = { PU4, 31 }, /* MSIOF0_SS1 */ - [RCAR_GP_PIN(5, 18)] = { PU4, 30 }, /* MSIOF0_SYNC */ - [RCAR_GP_PIN(5, 17)] = { PU4, 29 }, /* MSIOF0_SCK */ - [RCAR_GP_PIN(5, 16)] = { PU4, 28 }, /* HRTS0_N */ - [RCAR_GP_PIN(5, 15)] = { PU4, 27 }, /* HCTS0_N */ - [RCAR_GP_PIN(5, 14)] = { PU4, 26 }, /* HTX0 */ - [RCAR_GP_PIN(5, 13)] = { PU4, 25 }, /* HRX0 */ - [RCAR_GP_PIN(5, 12)] = { PU4, 24 }, /* HSCK0 */ - [RCAR_GP_PIN(5, 11)] = { PU4, 23 }, /* RX2_A */ - [RCAR_GP_PIN(5, 10)] = { PU4, 22 }, /* TX2_A */ - [RCAR_GP_PIN(5, 9)] = { PU4, 21 }, /* SCK2 */ - [RCAR_GP_PIN(5, 8)] = { PU4, 20 }, /* RTS1_N_TANS */ - [RCAR_GP_PIN(5, 7)] = { PU4, 19 }, /* CTS1_N */ - [RCAR_GP_PIN(5, 6)] = { PU4, 18 }, /* TX1_A */ - [RCAR_GP_PIN(5, 5)] = { PU4, 17 }, /* RX1_A */ - [RCAR_GP_PIN(5, 4)] = { PU4, 16 }, /* RTS0_N_TANS */ - [RCAR_GP_PIN(5, 3)] = { PU4, 15 }, /* CTS0_N */ - [RCAR_GP_PIN(5, 2)] = { PU4, 14 }, /* TX0 */ - [RCAR_GP_PIN(5, 1)] = { PU4, 13 }, /* RX0 */ - [RCAR_GP_PIN(5, 0)] = { PU4, 12 }, /* SCK0 */ - [RCAR_GP_PIN(3, 15)] = { PU4, 11 }, /* SD1_WP */ - [RCAR_GP_PIN(3, 14)] = { PU4, 10 }, /* SD1_CD */ - [RCAR_GP_PIN(3, 13)] = { PU4, 9 }, /* SD0_WP */ - [RCAR_GP_PIN(3, 12)] = { PU4, 8 }, /* SD0_CD */ - [RCAR_GP_PIN(4, 17)] = { PU4, 7 }, /* SD3_DS */ - [RCAR_GP_PIN(4, 16)] = { PU4, 6 }, /* SD3_DAT7 */ - [RCAR_GP_PIN(4, 15)] = { PU4, 5 }, /* SD3_DAT6 */ - [RCAR_GP_PIN(4, 14)] = { PU4, 4 }, /* SD3_DAT5 */ - [RCAR_GP_PIN(4, 13)] = { PU4, 3 }, /* SD3_DAT4 */ - [RCAR_GP_PIN(4, 12)] = { PU4, 2 }, /* SD3_DAT3 */ - [RCAR_GP_PIN(4, 11)] = { PU4, 1 }, /* SD3_DAT2 */ - [RCAR_GP_PIN(4, 10)] = { PU4, 0 }, /* SD3_DAT1 */ - - [RCAR_GP_PIN(6, 24)] = { PU5, 31 }, /* USB0_PWEN */ - [RCAR_GP_PIN(6, 23)] = { PU5, 30 }, /* AUDIO_CLKB_B */ - [RCAR_GP_PIN(6, 22)] = { PU5, 29 }, /* AUDIO_CLKA_A */ - [RCAR_GP_PIN(6, 21)] = { PU5, 28 }, /* SSI_SDATA9_A */ - [RCAR_GP_PIN(6, 20)] = { PU5, 27 }, /* SSI_SDATA8 */ - [RCAR_GP_PIN(6, 19)] = { PU5, 26 }, /* SSI_SDATA7 */ - [RCAR_GP_PIN(6, 18)] = { PU5, 25 }, /* SSI_WS78 */ - [RCAR_GP_PIN(6, 17)] = { PU5, 24 }, /* SSI_SCK78 */ - [RCAR_GP_PIN(6, 16)] = { PU5, 23 }, /* SSI_SDATA6 */ - [RCAR_GP_PIN(6, 15)] = { PU5, 22 }, /* SSI_WS6 */ - [RCAR_GP_PIN(6, 14)] = { PU5, 21 }, /* SSI_SCK6 */ - [RCAR_GP_PIN(6, 13)] = { PU5, 20 }, /* SSI_SDATA5 */ - [RCAR_GP_PIN(6, 12)] = { PU5, 19 }, /* SSI_WS5 */ - [RCAR_GP_PIN(6, 11)] = { PU5, 18 }, /* SSI_SCK5 */ - [RCAR_GP_PIN(6, 10)] = { PU5, 17 }, /* SSI_SDATA4 */ - [RCAR_GP_PIN(6, 9)] = { PU5, 16 }, /* SSI_WS4 */ - [RCAR_GP_PIN(6, 8)] = { PU5, 15 }, /* SSI_SCK4 */ - [RCAR_GP_PIN(6, 7)] = { PU5, 14 }, /* SSI_SDATA3 */ - [RCAR_GP_PIN(6, 6)] = { PU5, 13 }, /* SSI_WS34 */ - [RCAR_GP_PIN(6, 5)] = { PU5, 12 }, /* SSI_SCK34 */ - [RCAR_GP_PIN(6, 4)] = { PU5, 11 }, /* SSI_SDATA2_A */ - [RCAR_GP_PIN(6, 3)] = { PU5, 10 }, /* SSI_SDATA1_A */ - [RCAR_GP_PIN(6, 2)] = { PU5, 9 }, /* SSI_SDATA0 */ - [RCAR_GP_PIN(6, 1)] = { PU5, 8 }, /* SSI_WS01239 */ - [RCAR_GP_PIN(6, 0)] = { PU5, 7 }, /* SSI_SCK01239 */ - [RCAR_GP_PIN(5, 25)] = { PU5, 5 }, /* MLB_DAT */ - [RCAR_GP_PIN(5, 24)] = { PU5, 4 }, /* MLB_SIG */ - [RCAR_GP_PIN(5, 23)] = { PU5, 3 }, /* MLB_CLK */ - [RCAR_GP_PIN(5, 22)] = { PU5, 2 }, /* MSIOF0_RXD */ - [RCAR_GP_PIN(5, 21)] = { PU5, 1 }, /* MSIOF0_SS2 */ - [RCAR_GP_PIN(5, 20)] = { PU5, 0 }, /* MSIOF0_TXD */ - - [RCAR_GP_PIN(6, 31)] = { PU6, 6 }, /* USB31_OVC */ - [RCAR_GP_PIN(6, 30)] = { PU6, 5 }, /* USB31_PWEN */ - [RCAR_GP_PIN(6, 29)] = { PU6, 4 }, /* USB30_OVC */ - [RCAR_GP_PIN(6, 28)] = { PU6, 3 }, /* USB30_PWEN */ - [RCAR_GP_PIN(6, 27)] = { PU6, 2 }, /* USB1_OVC */ - [RCAR_GP_PIN(6, 26)] = { PU6, 1 }, /* USB1_PWEN */ - [RCAR_GP_PIN(6, 25)] = { PU6, 0 }, /* USB0_OVC */ +static const struct sh_pfc_bias_info bias_info[] = { + { RCAR_GP_PIN(2, 11), PU0, 31 }, /* AVB_PHY_INT */ + { RCAR_GP_PIN(2, 10), PU0, 30 }, /* AVB_MAGIC */ + { RCAR_GP_PIN(2, 9), PU0, 29 }, /* AVB_MDC */ + + { RCAR_GP_PIN(1, 19), PU1, 31 }, /* A19 */ + { RCAR_GP_PIN(1, 18), PU1, 30 }, /* A18 */ + { RCAR_GP_PIN(1, 17), PU1, 29 }, /* A17 */ + { RCAR_GP_PIN(1, 16), PU1, 28 }, /* A16 */ + { RCAR_GP_PIN(1, 15), PU1, 27 }, /* A15 */ + { RCAR_GP_PIN(1, 14), PU1, 26 }, /* A14 */ + { RCAR_GP_PIN(1, 13), PU1, 25 }, /* A13 */ + { RCAR_GP_PIN(1, 12), PU1, 24 }, /* A12 */ + { RCAR_GP_PIN(1, 11), PU1, 23 }, /* A11 */ + { RCAR_GP_PIN(1, 10), PU1, 22 }, /* A10 */ + { RCAR_GP_PIN(1, 9), PU1, 21 }, /* A9 */ + { RCAR_GP_PIN(1, 8), PU1, 20 }, /* A8 */ + { RCAR_GP_PIN(1, 7), PU1, 19 }, /* A7 */ + { RCAR_GP_PIN(1, 6), PU1, 18 }, /* A6 */ + { RCAR_GP_PIN(1, 5), PU1, 17 }, /* A5 */ + { RCAR_GP_PIN(1, 4), PU1, 16 }, /* A4 */ + { RCAR_GP_PIN(1, 3), PU1, 15 }, /* A3 */ + { RCAR_GP_PIN(1, 2), PU1, 14 }, /* A2 */ + { RCAR_GP_PIN(1, 1), PU1, 13 }, /* A1 */ + { RCAR_GP_PIN(1, 0), PU1, 12 }, /* A0 */ + { RCAR_GP_PIN(2, 8), PU1, 11 }, /* PWM2_A */ + { RCAR_GP_PIN(2, 7), PU1, 10 }, /* PWM1_A */ + { RCAR_GP_PIN(2, 6), PU1, 9 }, /* PWM0 */ + { RCAR_GP_PIN(2, 5), PU1, 8 }, /* IRQ5 */ + { RCAR_GP_PIN(2, 4), PU1, 7 }, /* IRQ4 */ + { RCAR_GP_PIN(2, 3), PU1, 6 }, /* IRQ3 */ + { RCAR_GP_PIN(2, 2), PU1, 5 }, /* IRQ2 */ + { RCAR_GP_PIN(2, 1), PU1, 4 }, /* IRQ1 */ + { RCAR_GP_PIN(2, 0), PU1, 3 }, /* IRQ0 */ + { RCAR_GP_PIN(2, 14), PU1, 2 }, /* AVB_AVTP_CAPTURE_A */ + { RCAR_GP_PIN(2, 13), PU1, 1 }, /* AVB_AVTP_MATCH_A */ + { RCAR_GP_PIN(2, 12), PU1, 0 }, /* AVB_LINK */ + + { RCAR_GP_PIN(7, 3), PU2, 29 }, /* HDMI1_CEC */ + { RCAR_GP_PIN(7, 2), PU2, 28 }, /* HDMI0_CEC */ + { RCAR_GP_PIN(7, 1), PU2, 27 }, /* AVS2 */ + { RCAR_GP_PIN(7, 0), PU2, 26 }, /* AVS1 */ + { RCAR_GP_PIN(0, 15), PU2, 25 }, /* D15 */ + { RCAR_GP_PIN(0, 14), PU2, 24 }, /* D14 */ + { RCAR_GP_PIN(0, 13), PU2, 23 }, /* D13 */ + { RCAR_GP_PIN(0, 12), PU2, 22 }, /* D12 */ + { RCAR_GP_PIN(0, 11), PU2, 21 }, /* D11 */ + { RCAR_GP_PIN(0, 10), PU2, 20 }, /* D10 */ + { RCAR_GP_PIN(0, 9), PU2, 19 }, /* D9 */ + { RCAR_GP_PIN(0, 8), PU2, 18 }, /* D8 */ + { RCAR_GP_PIN(0, 7), PU2, 17 }, /* D7 */ + { RCAR_GP_PIN(0, 6), PU2, 16 }, /* D6 */ + { RCAR_GP_PIN(0, 5), PU2, 15 }, /* D5 */ + { RCAR_GP_PIN(0, 4), PU2, 14 }, /* D4 */ + { RCAR_GP_PIN(0, 3), PU2, 13 }, /* D3 */ + { RCAR_GP_PIN(0, 2), PU2, 12 }, /* D2 */ + { RCAR_GP_PIN(0, 1), PU2, 11 }, /* D1 */ + { RCAR_GP_PIN(0, 0), PU2, 10 }, /* D0 */ + { RCAR_GP_PIN(1, 27), PU2, 8 }, /* EX_WAIT0_A */ + { RCAR_GP_PIN(1, 26), PU2, 7 }, /* WE1_N */ + { RCAR_GP_PIN(1, 25), PU2, 6 }, /* WE0_N */ + { RCAR_GP_PIN(1, 24), PU2, 5 }, /* RD_WR_N */ + { RCAR_GP_PIN(1, 23), PU2, 4 }, /* RD_N */ + { RCAR_GP_PIN(1, 22), PU2, 3 }, /* BS_N */ + { RCAR_GP_PIN(1, 21), PU2, 2 }, /* CS1_N_A26 */ + { RCAR_GP_PIN(1, 20), PU2, 1 }, /* CS0_N */ + + { RCAR_GP_PIN(4, 9), PU3, 31 }, /* SD3_DAT0 */ + { RCAR_GP_PIN(4, 8), PU3, 30 }, /* SD3_CMD */ + { RCAR_GP_PIN(4, 7), PU3, 29 }, /* SD3_CLK */ + { RCAR_GP_PIN(4, 6), PU3, 28 }, /* SD2_DS */ + { RCAR_GP_PIN(4, 5), PU3, 27 }, /* SD2_DAT3 */ + { RCAR_GP_PIN(4, 4), PU3, 26 }, /* SD2_DAT2 */ + { RCAR_GP_PIN(4, 3), PU3, 25 }, /* SD2_DAT1 */ + { RCAR_GP_PIN(4, 2), PU3, 24 }, /* SD2_DAT0 */ + { RCAR_GP_PIN(4, 1), PU3, 23 }, /* SD2_CMD */ + { RCAR_GP_PIN(4, 0), PU3, 22 }, /* SD2_CLK */ + { RCAR_GP_PIN(3, 11), PU3, 21 }, /* SD1_DAT3 */ + { RCAR_GP_PIN(3, 10), PU3, 20 }, /* SD1_DAT2 */ + { RCAR_GP_PIN(3, 9), PU3, 19 }, /* SD1_DAT1 */ + { RCAR_GP_PIN(3, 8), PU3, 18 }, /* SD1_DAT0 */ + { RCAR_GP_PIN(3, 7), PU3, 17 }, /* SD1_CMD */ + { RCAR_GP_PIN(3, 6), PU3, 16 }, /* SD1_CLK */ + { RCAR_GP_PIN(3, 5), PU3, 15 }, /* SD0_DAT3 */ + { RCAR_GP_PIN(3, 4), PU3, 14 }, /* SD0_DAT2 */ + { RCAR_GP_PIN(3, 3), PU3, 13 }, /* SD0_DAT1 */ + { RCAR_GP_PIN(3, 2), PU3, 12 }, /* SD0_DAT0 */ + { RCAR_GP_PIN(3, 1), PU3, 11 }, /* SD0_CMD */ + { RCAR_GP_PIN(3, 0), PU3, 10 }, /* SD0_CLK */ + + { RCAR_GP_PIN(5, 19), PU4, 31 }, /* MSIOF0_SS1 */ + { RCAR_GP_PIN(5, 18), PU4, 30 }, /* MSIOF0_SYNC */ + { RCAR_GP_PIN(5, 17), PU4, 29 }, /* MSIOF0_SCK */ + { RCAR_GP_PIN(5, 16), PU4, 28 }, /* HRTS0_N */ + { RCAR_GP_PIN(5, 15), PU4, 27 }, /* HCTS0_N */ + { RCAR_GP_PIN(5, 14), PU4, 26 }, /* HTX0 */ + { RCAR_GP_PIN(5, 13), PU4, 25 }, /* HRX0 */ + { RCAR_GP_PIN(5, 12), PU4, 24 }, /* HSCK0 */ + { RCAR_GP_PIN(5, 11), PU4, 23 }, /* RX2_A */ + { RCAR_GP_PIN(5, 10), PU4, 22 }, /* TX2_A */ + { RCAR_GP_PIN(5, 9), PU4, 21 }, /* SCK2 */ + { RCAR_GP_PIN(5, 8), PU4, 20 }, /* RTS1_N_TANS */ + { RCAR_GP_PIN(5, 7), PU4, 19 }, /* CTS1_N */ + { RCAR_GP_PIN(5, 6), PU4, 18 }, /* TX1_A */ + { RCAR_GP_PIN(5, 5), PU4, 17 }, /* RX1_A */ + { RCAR_GP_PIN(5, 4), PU4, 16 }, /* RTS0_N_TANS */ + { RCAR_GP_PIN(5, 3), PU4, 15 }, /* CTS0_N */ + { RCAR_GP_PIN(5, 2), PU4, 14 }, /* TX0 */ + { RCAR_GP_PIN(5, 1), PU4, 13 }, /* RX0 */ + { RCAR_GP_PIN(5, 0), PU4, 12 }, /* SCK0 */ + { RCAR_GP_PIN(3, 15), PU4, 11 }, /* SD1_WP */ + { RCAR_GP_PIN(3, 14), PU4, 10 }, /* SD1_CD */ + { RCAR_GP_PIN(3, 13), PU4, 9 }, /* SD0_WP */ + { RCAR_GP_PIN(3, 12), PU4, 8 }, /* SD0_CD */ + { RCAR_GP_PIN(4, 17), PU4, 7 }, /* SD3_DS */ + { RCAR_GP_PIN(4, 16), PU4, 6 }, /* SD3_DAT7 */ + { RCAR_GP_PIN(4, 15), PU4, 5 }, /* SD3_DAT6 */ + { RCAR_GP_PIN(4, 14), PU4, 4 }, /* SD3_DAT5 */ + { RCAR_GP_PIN(4, 13), PU4, 3 }, /* SD3_DAT4 */ + { RCAR_GP_PIN(4, 12), PU4, 2 }, /* SD3_DAT3 */ + { RCAR_GP_PIN(4, 11), PU4, 1 }, /* SD3_DAT2 */ + { RCAR_GP_PIN(4, 10), PU4, 0 }, /* SD3_DAT1 */ + + { RCAR_GP_PIN(6, 24), PU5, 31 }, /* USB0_PWEN */ + { RCAR_GP_PIN(6, 23), PU5, 30 }, /* AUDIO_CLKB_B */ + { RCAR_GP_PIN(6, 22), PU5, 29 }, /* AUDIO_CLKA_A */ + { RCAR_GP_PIN(6, 21), PU5, 28 }, /* SSI_SDATA9_A */ + { RCAR_GP_PIN(6, 20), PU5, 27 }, /* SSI_SDATA8 */ + { RCAR_GP_PIN(6, 19), PU5, 26 }, /* SSI_SDATA7 */ + { RCAR_GP_PIN(6, 18), PU5, 25 }, /* SSI_WS78 */ + { RCAR_GP_PIN(6, 17), PU5, 24 }, /* SSI_SCK78 */ + { RCAR_GP_PIN(6, 16), PU5, 23 }, /* SSI_SDATA6 */ + { RCAR_GP_PIN(6, 15), PU5, 22 }, /* SSI_WS6 */ + { RCAR_GP_PIN(6, 14), PU5, 21 }, /* SSI_SCK6 */ + { RCAR_GP_PIN(6, 13), PU5, 20 }, /* SSI_SDATA5 */ + { RCAR_GP_PIN(6, 12), PU5, 19 }, /* SSI_WS5 */ + { RCAR_GP_PIN(6, 11), PU5, 18 }, /* SSI_SCK5 */ + { RCAR_GP_PIN(6, 10), PU5, 17 }, /* SSI_SDATA4 */ + { RCAR_GP_PIN(6, 9), PU5, 16 }, /* SSI_WS4 */ + { RCAR_GP_PIN(6, 8), PU5, 15 }, /* SSI_SCK4 */ + { RCAR_GP_PIN(6, 7), PU5, 14 }, /* SSI_SDATA3 */ + { RCAR_GP_PIN(6, 6), PU5, 13 }, /* SSI_WS34 */ + { RCAR_GP_PIN(6, 5), PU5, 12 }, /* SSI_SCK34 */ + { RCAR_GP_PIN(6, 4), PU5, 11 }, /* SSI_SDATA2_A */ + { RCAR_GP_PIN(6, 3), PU5, 10 }, /* SSI_SDATA1_A */ + { RCAR_GP_PIN(6, 2), PU5, 9 }, /* SSI_SDATA0 */ + { RCAR_GP_PIN(6, 1), PU5, 8 }, /* SSI_WS01239 */ + { RCAR_GP_PIN(6, 0), PU5, 7 }, /* SSI_SCK01239 */ + { RCAR_GP_PIN(5, 25), PU5, 5 }, /* MLB_DAT */ + { RCAR_GP_PIN(5, 24), PU5, 4 }, /* MLB_SIG */ + { RCAR_GP_PIN(5, 23), PU5, 3 }, /* MLB_CLK */ + { RCAR_GP_PIN(5, 22), PU5, 2 }, /* MSIOF0_RXD */ + { RCAR_GP_PIN(5, 21), PU5, 1 }, /* MSIOF0_SS2 */ + { RCAR_GP_PIN(5, 20), PU5, 0 }, /* MSIOF0_TXD */ + + { RCAR_GP_PIN(6, 31), PU6, 6 }, /* USB31_OVC */ + { RCAR_GP_PIN(6, 30), PU6, 5 }, /* USB31_PWEN */ + { RCAR_GP_PIN(6, 29), PU6, 4 }, /* USB30_OVC */ + { RCAR_GP_PIN(6, 28), PU6, 3 }, /* USB30_PWEN */ + { RCAR_GP_PIN(6, 27), PU6, 2 }, /* USB1_OVC */ + { RCAR_GP_PIN(6, 26), PU6, 1 }, /* USB1_PWEN */ + { RCAR_GP_PIN(6, 25), PU6, 0 }, /* USB0_OVC */ }; static unsigned int r8a7795_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin) { + const struct sh_pfc_bias_info *info; u32 reg; u32 bit; - if (WARN_ON_ONCE(!pullups[pin].reg)) + info = sh_pfc_pin_to_bias_info(bias_info, ARRAY_SIZE(bias_info), pin); + if (!info) return PIN_CONFIG_BIAS_DISABLE; - reg = pullups[pin].reg; - bit = BIT(pullups[pin].bit); + reg = info->reg; + bit = BIT(info->bit); - if (sh_pfc_read_reg(pfc, PUEN + reg, 32) & bit) { - if (sh_pfc_read_reg(pfc, PUD + reg, 32) & bit) - return PIN_CONFIG_BIAS_PULL_UP; - else - return PIN_CONFIG_BIAS_PULL_DOWN; - } else + if (!(sh_pfc_read_reg(pfc, PUEN + reg, 32) & bit)) return PIN_CONFIG_BIAS_DISABLE; + else if (sh_pfc_read_reg(pfc, PUD + reg, 32) & bit) + return PIN_CONFIG_BIAS_PULL_UP; + else + return PIN_CONFIG_BIAS_PULL_DOWN; } static void r8a7795_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, unsigned int bias) { + const struct sh_pfc_bias_info *info; u32 enable, updown; u32 reg; u32 bit; - if (WARN_ON_ONCE(!pullups[pin].reg)) + info = sh_pfc_pin_to_bias_info(bias_info, ARRAY_SIZE(bias_info), pin); + if (!info) return; - reg = pullups[pin].reg; - bit = BIT(pullups[pin].bit); + reg = info->reg; + bit = BIT(info->bit); enable = sh_pfc_read_reg(pfc, PUEN + reg, 32) & ~bit; if (bias != PIN_CONFIG_BIAS_DISABLE) diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7796.c b/drivers/pinctrl/sh-pfc/pfc-r8a7796.c index dc9b671ccf2e..7e16545a2c3c 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7796.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7796.c @@ -122,22 +122,22 @@ #define GPSR3_0 F_(SD0_CLK, IP7_19_16) /* GPSR4 */ -#define GPSR4_17 F_(SD3_DS, IP11_11_8) -#define GPSR4_16 F_(SD3_DAT7, IP10_7_4) -#define GPSR4_15 F_(SD3_DAT6, IP10_3_0) -#define GPSR4_14 F_(SD3_DAT5, IP9_31_28) -#define GPSR4_13 F_(SD3_DAT4, IP9_27_24) +#define GPSR4_17 F_(SD3_DS, IP11_7_4) +#define GPSR4_16 F_(SD3_DAT7, IP11_3_0) +#define GPSR4_15 F_(SD3_DAT6, IP10_31_28) +#define GPSR4_14 F_(SD3_DAT5, IP10_27_24) +#define GPSR4_13 F_(SD3_DAT4, IP10_23_20) #define GPSR4_12 F_(SD3_DAT3, IP10_19_16) #define GPSR4_11 F_(SD3_DAT2, IP10_15_12) #define GPSR4_10 F_(SD3_DAT1, IP10_11_8) #define GPSR4_9 F_(SD3_DAT0, IP10_7_4) #define GPSR4_8 F_(SD3_CMD, IP10_3_0) #define GPSR4_7 F_(SD3_CLK, IP9_31_28) -#define GPSR4_6 F_(SD2_DS, IP9_23_20) -#define GPSR4_5 F_(SD2_DAT3, IP9_19_16) -#define GPSR4_4 F_(SD2_DAT2, IP9_15_12) -#define GPSR4_3 F_(SD2_DAT1, IP9_11_8) -#define GPSR4_2 F_(SD2_DAT0, IP9_7_4) +#define GPSR4_6 F_(SD2_DS, IP9_27_24) +#define GPSR4_5 F_(SD2_DAT3, IP9_23_20) +#define GPSR4_4 F_(SD2_DAT2, IP9_19_16) +#define GPSR4_3 F_(SD2_DAT1, IP9_15_12) +#define GPSR4_2 F_(SD2_DAT0, IP9_11_8) #define GPSR4_1 F_(SD2_CMD, IP9_7_4) #define GPSR4_0 F_(SD2_CLK, IP9_3_0) @@ -1490,6 +1490,418 @@ static const struct sh_pfc_pin pinmux_pins[] = { PINMUX_GPIO_GP_ALL(), }; +/* - EtherAVB --------------------------------------------------------------- */ +static const unsigned int avb_link_pins[] = { + /* AVB_LINK */ + RCAR_GP_PIN(2, 12), +}; +static const unsigned int avb_link_mux[] = { + AVB_LINK_MARK, +}; +static const unsigned int avb_magic_pins[] = { + /* AVB_MAGIC_ */ + RCAR_GP_PIN(2, 10), +}; +static const unsigned int avb_magic_mux[] = { + AVB_MAGIC_MARK, +}; +static const unsigned int avb_phy_int_pins[] = { + /* AVB_PHY_INT */ + RCAR_GP_PIN(2, 11), +}; +static const unsigned int avb_phy_int_mux[] = { + AVB_PHY_INT_MARK, +}; +static const unsigned int avb_mdc_pins[] = { + /* AVB_MDC */ + RCAR_GP_PIN(2, 9), +}; +static const unsigned int avb_mdc_mux[] = { + AVB_MDC_MARK, +}; +static const unsigned int avb_avtp_pps_pins[] = { + /* AVB_AVTP_PPS */ + RCAR_GP_PIN(2, 6), +}; +static const unsigned int avb_avtp_pps_mux[] = { + AVB_AVTP_PPS_MARK, +}; +static const unsigned int avb_avtp_match_a_pins[] = { + /* AVB_AVTP_MATCH_A */ + RCAR_GP_PIN(2, 13), +}; +static const unsigned int avb_avtp_match_a_mux[] = { + AVB_AVTP_MATCH_A_MARK, +}; +static const unsigned int avb_avtp_capture_a_pins[] = { + /* AVB_AVTP_CAPTURE_A */ + RCAR_GP_PIN(2, 14), +}; +static const unsigned int avb_avtp_capture_a_mux[] = { + AVB_AVTP_CAPTURE_A_MARK, +}; +static const unsigned int avb_avtp_match_b_pins[] = { + /* AVB_AVTP_MATCH_B */ + RCAR_GP_PIN(1, 8), +}; +static const unsigned int avb_avtp_match_b_mux[] = { + AVB_AVTP_MATCH_B_MARK, +}; +static const unsigned int avb_avtp_capture_b_pins[] = { + /* AVB_AVTP_CAPTURE_B */ + RCAR_GP_PIN(1, 11), +}; +static const unsigned int avb_avtp_capture_b_mux[] = { + AVB_AVTP_CAPTURE_B_MARK, +}; + +/* - DRIF0 --------------------------------------------------------------- */ +static const unsigned int drif0_ctrl_a_pins[] = { + /* CLK, SYNC */ + RCAR_GP_PIN(6, 8), RCAR_GP_PIN(6, 9), +}; +static const unsigned int drif0_ctrl_a_mux[] = { + RIF0_CLK_A_MARK, RIF0_SYNC_A_MARK, +}; +static const unsigned int drif0_data0_a_pins[] = { + /* D0 */ + RCAR_GP_PIN(6, 10), +}; +static const unsigned int drif0_data0_a_mux[] = { + RIF0_D0_A_MARK, +}; +static const unsigned int drif0_data1_a_pins[] = { + /* D1 */ + RCAR_GP_PIN(6, 7), +}; +static const unsigned int drif0_data1_a_mux[] = { + RIF0_D1_A_MARK, +}; +static const unsigned int drif0_ctrl_b_pins[] = { + /* CLK, SYNC */ + RCAR_GP_PIN(5, 0), RCAR_GP_PIN(5, 4), +}; +static const unsigned int drif0_ctrl_b_mux[] = { + RIF0_CLK_B_MARK, RIF0_SYNC_B_MARK, +}; +static const unsigned int drif0_data0_b_pins[] = { + /* D0 */ + RCAR_GP_PIN(5, 1), +}; +static const unsigned int drif0_data0_b_mux[] = { + RIF0_D0_B_MARK, +}; +static const unsigned int drif0_data1_b_pins[] = { + /* D1 */ + RCAR_GP_PIN(5, 2), +}; +static const unsigned int drif0_data1_b_mux[] = { + RIF0_D1_B_MARK, +}; +static const unsigned int drif0_ctrl_c_pins[] = { + /* CLK, SYNC */ + RCAR_GP_PIN(5, 12), RCAR_GP_PIN(5, 15), +}; +static const unsigned int drif0_ctrl_c_mux[] = { + RIF0_CLK_C_MARK, RIF0_SYNC_C_MARK, +}; +static const unsigned int drif0_data0_c_pins[] = { + /* D0 */ + RCAR_GP_PIN(5, 13), +}; +static const unsigned int drif0_data0_c_mux[] = { + RIF0_D0_C_MARK, +}; +static const unsigned int drif0_data1_c_pins[] = { + /* D1 */ + RCAR_GP_PIN(5, 14), +}; +static const unsigned int drif0_data1_c_mux[] = { + RIF0_D1_C_MARK, +}; +/* - DRIF1 --------------------------------------------------------------- */ +static const unsigned int drif1_ctrl_a_pins[] = { + /* CLK, SYNC */ + RCAR_GP_PIN(6, 17), RCAR_GP_PIN(6, 18), +}; +static const unsigned int drif1_ctrl_a_mux[] = { + RIF1_CLK_A_MARK, RIF1_SYNC_A_MARK, +}; +static const unsigned int drif1_data0_a_pins[] = { + /* D0 */ + RCAR_GP_PIN(6, 19), +}; +static const unsigned int drif1_data0_a_mux[] = { + RIF1_D0_A_MARK, +}; +static const unsigned int drif1_data1_a_pins[] = { + /* D1 */ + RCAR_GP_PIN(6, 20), +}; +static const unsigned int drif1_data1_a_mux[] = { + RIF1_D1_A_MARK, +}; +static const unsigned int drif1_ctrl_b_pins[] = { + /* CLK, SYNC */ + RCAR_GP_PIN(5, 9), RCAR_GP_PIN(5, 3), +}; +static const unsigned int drif1_ctrl_b_mux[] = { + RIF1_CLK_B_MARK, RIF1_SYNC_B_MARK, +}; +static const unsigned int drif1_data0_b_pins[] = { + /* D0 */ + RCAR_GP_PIN(5, 7), +}; +static const unsigned int drif1_data0_b_mux[] = { + RIF1_D0_B_MARK, +}; +static const unsigned int drif1_data1_b_pins[] = { + /* D1 */ + RCAR_GP_PIN(5, 8), +}; +static const unsigned int drif1_data1_b_mux[] = { + RIF1_D1_B_MARK, +}; +static const unsigned int drif1_ctrl_c_pins[] = { + /* CLK, SYNC */ + RCAR_GP_PIN(5, 5), RCAR_GP_PIN(5, 11), +}; +static const unsigned int drif1_ctrl_c_mux[] = { + RIF1_CLK_C_MARK, RIF1_SYNC_C_MARK, +}; +static const unsigned int drif1_data0_c_pins[] = { + /* D0 */ + RCAR_GP_PIN(5, 6), +}; +static const unsigned int drif1_data0_c_mux[] = { + RIF1_D0_C_MARK, +}; +static const unsigned int drif1_data1_c_pins[] = { + /* D1 */ + RCAR_GP_PIN(5, 10), +}; +static const unsigned int drif1_data1_c_mux[] = { + RIF1_D1_C_MARK, +}; +/* - DRIF2 --------------------------------------------------------------- */ +static const unsigned int drif2_ctrl_a_pins[] = { + /* CLK, SYNC */ + RCAR_GP_PIN(6, 8), RCAR_GP_PIN(6, 9), +}; +static const unsigned int drif2_ctrl_a_mux[] = { + RIF2_CLK_A_MARK, RIF2_SYNC_A_MARK, +}; +static const unsigned int drif2_data0_a_pins[] = { + /* D0 */ + RCAR_GP_PIN(6, 7), +}; +static const unsigned int drif2_data0_a_mux[] = { + RIF2_D0_A_MARK, +}; +static const unsigned int drif2_data1_a_pins[] = { + /* D1 */ + RCAR_GP_PIN(6, 10), +}; +static const unsigned int drif2_data1_a_mux[] = { + RIF2_D1_A_MARK, +}; +static const unsigned int drif2_ctrl_b_pins[] = { + /* CLK, SYNC */ + RCAR_GP_PIN(6, 26), RCAR_GP_PIN(6, 27), +}; +static const unsigned int drif2_ctrl_b_mux[] = { + RIF2_CLK_B_MARK, RIF2_SYNC_B_MARK, +}; +static const unsigned int drif2_data0_b_pins[] = { + /* D0 */ + RCAR_GP_PIN(6, 30), +}; +static const unsigned int drif2_data0_b_mux[] = { + RIF2_D0_B_MARK, +}; +static const unsigned int drif2_data1_b_pins[] = { + /* D1 */ + RCAR_GP_PIN(6, 31), +}; +static const unsigned int drif2_data1_b_mux[] = { + RIF2_D1_B_MARK, +}; +/* - DRIF3 --------------------------------------------------------------- */ +static const unsigned int drif3_ctrl_a_pins[] = { + /* CLK, SYNC */ + RCAR_GP_PIN(6, 17), RCAR_GP_PIN(6, 18), +}; +static const unsigned int drif3_ctrl_a_mux[] = { + RIF3_CLK_A_MARK, RIF3_SYNC_A_MARK, +}; +static const unsigned int drif3_data0_a_pins[] = { + /* D0 */ + RCAR_GP_PIN(6, 19), +}; +static const unsigned int drif3_data0_a_mux[] = { + RIF3_D0_A_MARK, +}; +static const unsigned int drif3_data1_a_pins[] = { + /* D1 */ + RCAR_GP_PIN(6, 20), +}; +static const unsigned int drif3_data1_a_mux[] = { + RIF3_D1_A_MARK, +}; +static const unsigned int drif3_ctrl_b_pins[] = { + /* CLK, SYNC */ + RCAR_GP_PIN(6, 24), RCAR_GP_PIN(6, 25), +}; +static const unsigned int drif3_ctrl_b_mux[] = { + RIF3_CLK_B_MARK, RIF3_SYNC_B_MARK, +}; +static const unsigned int drif3_data0_b_pins[] = { + /* D0 */ + RCAR_GP_PIN(6, 28), +}; +static const unsigned int drif3_data0_b_mux[] = { + RIF3_D0_B_MARK, +}; +static const unsigned int drif3_data1_b_pins[] = { + /* D1 */ + RCAR_GP_PIN(6, 29), +}; +static const unsigned int drif3_data1_b_mux[] = { + RIF3_D1_B_MARK, +}; + +/* - DU --------------------------------------------------------------------- */ +static const unsigned int du_rgb666_pins[] = { + /* R[7:2], G[7:2], B[7:2] */ + RCAR_GP_PIN(0, 15), RCAR_GP_PIN(0, 14), RCAR_GP_PIN(0, 13), + RCAR_GP_PIN(0, 12), RCAR_GP_PIN(0, 11), RCAR_GP_PIN(0, 10), + RCAR_GP_PIN(1, 15), RCAR_GP_PIN(1, 14), RCAR_GP_PIN(1, 13), + RCAR_GP_PIN(1, 12), RCAR_GP_PIN(1, 19), RCAR_GP_PIN(1, 18), + RCAR_GP_PIN(1, 7), RCAR_GP_PIN(1, 6), RCAR_GP_PIN(1, 5), + RCAR_GP_PIN(1, 4), RCAR_GP_PIN(1, 3), RCAR_GP_PIN(1, 2), +}; +static const unsigned int du_rgb666_mux[] = { + DU_DR7_MARK, DU_DR6_MARK, DU_DR5_MARK, DU_DR4_MARK, + DU_DR3_MARK, DU_DR2_MARK, + DU_DG7_MARK, DU_DG6_MARK, DU_DG5_MARK, DU_DG4_MARK, + DU_DG3_MARK, DU_DG2_MARK, + DU_DB7_MARK, DU_DB6_MARK, DU_DB5_MARK, DU_DB4_MARK, + DU_DB3_MARK, DU_DB2_MARK, +}; +static const unsigned int du_rgb888_pins[] = { + /* R[7:0], G[7:0], B[7:0] */ + RCAR_GP_PIN(0, 15), RCAR_GP_PIN(0, 14), RCAR_GP_PIN(0, 13), + RCAR_GP_PIN(0, 12), RCAR_GP_PIN(0, 11), RCAR_GP_PIN(0, 10), + RCAR_GP_PIN(0, 9), RCAR_GP_PIN(0, 8), + RCAR_GP_PIN(1, 15), RCAR_GP_PIN(1, 14), RCAR_GP_PIN(1, 13), + RCAR_GP_PIN(1, 12), RCAR_GP_PIN(1, 19), RCAR_GP_PIN(1, 18), + RCAR_GP_PIN(1, 17), RCAR_GP_PIN(1, 16), + RCAR_GP_PIN(1, 7), RCAR_GP_PIN(1, 6), RCAR_GP_PIN(1, 5), + RCAR_GP_PIN(1, 4), RCAR_GP_PIN(1, 3), RCAR_GP_PIN(1, 2), + RCAR_GP_PIN(1, 1), RCAR_GP_PIN(1, 0), +}; +static const unsigned int du_rgb888_mux[] = { + DU_DR7_MARK, DU_DR6_MARK, DU_DR5_MARK, DU_DR4_MARK, + DU_DR3_MARK, DU_DR2_MARK, DU_DR1_MARK, DU_DR0_MARK, + DU_DG7_MARK, DU_DG6_MARK, DU_DG5_MARK, DU_DG4_MARK, + DU_DG3_MARK, DU_DG2_MARK, DU_DG1_MARK, DU_DG0_MARK, + DU_DB7_MARK, DU_DB6_MARK, DU_DB5_MARK, DU_DB4_MARK, + DU_DB3_MARK, DU_DB2_MARK, DU_DB1_MARK, DU_DB0_MARK, +}; +static const unsigned int du_clk_out_0_pins[] = { + /* CLKOUT */ + RCAR_GP_PIN(1, 27), +}; +static const unsigned int du_clk_out_0_mux[] = { + DU_DOTCLKOUT0_MARK +}; +static const unsigned int du_clk_out_1_pins[] = { + /* CLKOUT */ + RCAR_GP_PIN(2, 3), +}; +static const unsigned int du_clk_out_1_mux[] = { + DU_DOTCLKOUT1_MARK +}; +static const unsigned int du_sync_pins[] = { + /* EXVSYNC/VSYNC, EXHSYNC/HSYNC */ + RCAR_GP_PIN(2, 5), RCAR_GP_PIN(2, 4), +}; +static const unsigned int du_sync_mux[] = { + DU_EXVSYNC_DU_VSYNC_MARK, DU_EXHSYNC_DU_HSYNC_MARK +}; +static const unsigned int du_oddf_pins[] = { + /* EXDISP/EXODDF/EXCDE */ + RCAR_GP_PIN(2, 2), +}; +static const unsigned int du_oddf_mux[] = { + DU_EXODDF_DU_ODDF_DISP_CDE_MARK, +}; +static const unsigned int du_cde_pins[] = { + /* CDE */ + RCAR_GP_PIN(2, 0), +}; +static const unsigned int du_cde_mux[] = { + DU_CDE_MARK, +}; +static const unsigned int du_disp_pins[] = { + /* DISP */ + RCAR_GP_PIN(2, 1), +}; +static const unsigned int du_disp_mux[] = { + DU_DISP_MARK, +}; + +/* - I2C -------------------------------------------------------------------- */ +static const unsigned int i2c1_a_pins[] = { + /* SDA, SCL */ + RCAR_GP_PIN(5, 11), RCAR_GP_PIN(5, 10), +}; +static const unsigned int i2c1_a_mux[] = { + SDA1_A_MARK, SCL1_A_MARK, +}; +static const unsigned int i2c1_b_pins[] = { + /* SDA, SCL */ + RCAR_GP_PIN(5, 24), RCAR_GP_PIN(5, 23), +}; +static const unsigned int i2c1_b_mux[] = { + SDA1_B_MARK, SCL1_B_MARK, +}; +static const unsigned int i2c2_a_pins[] = { + /* SDA, SCL */ + RCAR_GP_PIN(5, 0), RCAR_GP_PIN(5, 4), +}; +static const unsigned int i2c2_a_mux[] = { + SDA2_A_MARK, SCL2_A_MARK, +}; +static const unsigned int i2c2_b_pins[] = { + /* SDA, SCL */ + RCAR_GP_PIN(3, 13), RCAR_GP_PIN(3, 12), +}; +static const unsigned int i2c2_b_mux[] = { + SDA2_B_MARK, SCL2_B_MARK, +}; +static const unsigned int i2c6_a_pins[] = { + /* SDA, SCL */ + RCAR_GP_PIN(1, 8), RCAR_GP_PIN(1, 11), +}; +static const unsigned int i2c6_a_mux[] = { + SDA6_A_MARK, SCL6_A_MARK, +}; +static const unsigned int i2c6_b_pins[] = { + /* SDA, SCL */ + RCAR_GP_PIN(1, 26), RCAR_GP_PIN(1, 25), +}; +static const unsigned int i2c6_b_mux[] = { + SDA6_B_MARK, SCL6_B_MARK, +}; +static const unsigned int i2c6_c_pins[] = { + /* SDA, SCL */ + RCAR_GP_PIN(0, 15), RCAR_GP_PIN(0, 14), +}; +static const unsigned int i2c6_c_mux[] = { + SDA6_C_MARK, SCL6_C_MARK, +}; + /* - SCIF0 ------------------------------------------------------------------ */ static const unsigned int scif0_data_pins[] = { /* RX, TX */ @@ -1912,6 +2324,60 @@ static const unsigned int sdhi3_ds_mux[] = { }; static const struct sh_pfc_pin_group pinmux_groups[] = { + SH_PFC_PIN_GROUP(avb_link), + SH_PFC_PIN_GROUP(avb_magic), + SH_PFC_PIN_GROUP(avb_phy_int), + SH_PFC_PIN_GROUP(avb_mdc), + SH_PFC_PIN_GROUP(avb_avtp_pps), + SH_PFC_PIN_GROUP(avb_avtp_match_a), + SH_PFC_PIN_GROUP(avb_avtp_capture_a), + SH_PFC_PIN_GROUP(avb_avtp_match_b), + SH_PFC_PIN_GROUP(avb_avtp_capture_b), + SH_PFC_PIN_GROUP(drif0_ctrl_a), + SH_PFC_PIN_GROUP(drif0_data0_a), + SH_PFC_PIN_GROUP(drif0_data1_a), + SH_PFC_PIN_GROUP(drif0_ctrl_b), + SH_PFC_PIN_GROUP(drif0_data0_b), + SH_PFC_PIN_GROUP(drif0_data1_b), + SH_PFC_PIN_GROUP(drif0_ctrl_c), + SH_PFC_PIN_GROUP(drif0_data0_c), + SH_PFC_PIN_GROUP(drif0_data1_c), + SH_PFC_PIN_GROUP(drif1_ctrl_a), + SH_PFC_PIN_GROUP(drif1_data0_a), + SH_PFC_PIN_GROUP(drif1_data1_a), + SH_PFC_PIN_GROUP(drif1_ctrl_b), + SH_PFC_PIN_GROUP(drif1_data0_b), + SH_PFC_PIN_GROUP(drif1_data1_b), + SH_PFC_PIN_GROUP(drif1_ctrl_c), + SH_PFC_PIN_GROUP(drif1_data0_c), + SH_PFC_PIN_GROUP(drif1_data1_c), + SH_PFC_PIN_GROUP(drif2_ctrl_a), + SH_PFC_PIN_GROUP(drif2_data0_a), + SH_PFC_PIN_GROUP(drif2_data1_a), + SH_PFC_PIN_GROUP(drif2_ctrl_b), + SH_PFC_PIN_GROUP(drif2_data0_b), + SH_PFC_PIN_GROUP(drif2_data1_b), + SH_PFC_PIN_GROUP(drif3_ctrl_a), + SH_PFC_PIN_GROUP(drif3_data0_a), + SH_PFC_PIN_GROUP(drif3_data1_a), + SH_PFC_PIN_GROUP(drif3_ctrl_b), + SH_PFC_PIN_GROUP(drif3_data0_b), + SH_PFC_PIN_GROUP(drif3_data1_b), + SH_PFC_PIN_GROUP(du_rgb666), + SH_PFC_PIN_GROUP(du_rgb888), + SH_PFC_PIN_GROUP(du_clk_out_0), + SH_PFC_PIN_GROUP(du_clk_out_1), + SH_PFC_PIN_GROUP(du_sync), + SH_PFC_PIN_GROUP(du_oddf), + SH_PFC_PIN_GROUP(du_cde), + SH_PFC_PIN_GROUP(du_disp), + SH_PFC_PIN_GROUP(i2c1_a), + SH_PFC_PIN_GROUP(i2c1_b), + SH_PFC_PIN_GROUP(i2c2_a), + SH_PFC_PIN_GROUP(i2c2_b), + SH_PFC_PIN_GROUP(i2c6_a), + SH_PFC_PIN_GROUP(i2c6_b), + SH_PFC_PIN_GROUP(i2c6_c), SH_PFC_PIN_GROUP(scif0_data), SH_PFC_PIN_GROUP(scif0_clk), SH_PFC_PIN_GROUP(scif0_ctrl), @@ -1969,6 +2435,87 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(sdhi3_ds), }; +static const char * const avb_groups[] = { + "avb_link", + "avb_magic", + "avb_phy_int", + "avb_mdc", + "avb_avtp_pps", + "avb_avtp_match_a", + "avb_avtp_capture_a", + "avb_avtp_match_b", + "avb_avtp_capture_b", +}; + +static const char * const drif0_groups[] = { + "drif0_ctrl_a", + "drif0_data0_a", + "drif0_data1_a", + "drif0_ctrl_b", + "drif0_data0_b", + "drif0_data1_b", + "drif0_ctrl_c", + "drif0_data0_c", + "drif0_data1_c", +}; + +static const char * const drif1_groups[] = { + "drif1_ctrl_a", + "drif1_data0_a", + "drif1_data1_a", + "drif1_ctrl_b", + "drif1_data0_b", + "drif1_data1_b", + "drif1_ctrl_c", + "drif1_data0_c", + "drif1_data1_c", +}; + +static const char * const drif2_groups[] = { + "drif2_ctrl_a", + "drif2_data0_a", + "drif2_data1_a", + "drif2_ctrl_b", + "drif2_data0_b", + "drif2_data1_b", +}; + +static const char * const drif3_groups[] = { + "drif3_ctrl_a", + "drif3_data0_a", + "drif3_data1_a", + "drif3_ctrl_b", + "drif3_data0_b", + "drif3_data1_b", +}; + +static const char * const du_groups[] = { + "du_rgb666", + "du_rgb888", + "du_clk_out_0", + "du_clk_out_1", + "du_sync", + "du_oddf", + "du_cde", + "du_disp", +}; + +static const char * const i2c1_groups[] = { + "i2c1_a", + "i2c1_b", +}; + +static const char * const i2c2_groups[] = { + "i2c2_a", + "i2c2_b", +}; + +static const char * const i2c6_groups[] = { + "i2c6_a", + "i2c6_b", + "i2c6_c", +}; + static const char * const scif0_groups[] = { "scif0_data", "scif0_clk", @@ -2058,6 +2605,15 @@ static const char * const sdhi3_groups[] = { }; static const struct sh_pfc_function pinmux_functions[] = { + SH_PFC_FUNCTION(avb), + SH_PFC_FUNCTION(drif0), + SH_PFC_FUNCTION(drif1), + SH_PFC_FUNCTION(drif2), + SH_PFC_FUNCTION(drif3), + SH_PFC_FUNCTION(du), + SH_PFC_FUNCTION(i2c1), + SH_PFC_FUNCTION(i2c2), + SH_PFC_FUNCTION(i2c6), SH_PFC_FUNCTION(scif0), SH_PFC_FUNCTION(scif1), SH_PFC_FUNCTION(scif2), diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index c5772584594c..fcacfa73ef6e 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -570,7 +570,8 @@ static bool sh_pfc_pinconf_validate(struct sh_pfc *pfc, unsigned int _pin, switch (param) { case PIN_CONFIG_BIAS_DISABLE: - return true; + return pin->configs & + (SH_PFC_PIN_CFG_PULL_UP | SH_PFC_PIN_CFG_PULL_DOWN); case PIN_CONFIG_BIAS_PULL_UP: return pin->configs & SH_PFC_PIN_CFG_PULL_UP; diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index 2345421103db..e42cc7a8d10e 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -189,6 +189,12 @@ struct sh_pfc_window { unsigned long size; }; +struct sh_pfc_bias_info { + u16 pin; + u16 reg : 11; + u16 bit : 5; +}; + struct sh_pfc_pin_range; struct sh_pfc { @@ -540,6 +546,14 @@ extern const struct sh_pfc_soc_info shx3_pinmux_info; .configs = SH_PFC_PIN_CFG_NO_GPIO, \ } +/* SH_PFC_PIN_NAMED_CFG - Expand to a sh_pfc_pin entry with the given name */ +#define SH_PFC_PIN_NAMED_CFG(row, col, _name, cfgs) \ + { \ + .pin = PIN_NUMBER(row, col), \ + .name = __stringify(PIN_##_name), \ + .configs = SH_PFC_PIN_CFG_NO_GPIO | cfgs, \ + } + /* PINMUX_DATA_ALL - Expand to a list of PORT_name_DATA, PORT_name_FN0, * PORT_name_OUT, PORT_name_IN marks */ diff --git a/drivers/pinctrl/stm32/pinctrl-stm32f429.c b/drivers/pinctrl/stm32/pinctrl-stm32f429.c index e9b15dc0654b..990b867b9625 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32f429.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32f429.c @@ -1584,8 +1584,4 @@ static struct platform_driver stm32f429_pinctrl_driver = { }, }; -static int __init stm32f429_pinctrl_init(void) -{ - return platform_driver_register(&stm32f429_pinctrl_driver); -} -device_initcall(stm32f429_pinctrl_init); +builtin_platform_driver(stm32f429_pinctrl_driver); diff --git a/drivers/pinctrl/sunxi/pinctrl-gr8.c b/drivers/pinctrl/sunxi/pinctrl-gr8.c index 2904d2b7378b..2f232c3a0579 100644 --- a/drivers/pinctrl/sunxi/pinctrl-gr8.c +++ b/drivers/pinctrl/sunxi/pinctrl-gr8.c @@ -12,7 +12,7 @@ * warranty of any kind, whether express or implied. */ -#include <linux/module.h> +#include <linux/init.h> #include <linux/platform_device.h> #include <linux/of.h> #include <linux/of_device.h> @@ -525,7 +525,6 @@ static const struct of_device_id sun5i_gr8_pinctrl_match[] = { { .compatible = "nextthing,gr8-pinctrl", }, {} }; -MODULE_DEVICE_TABLE(of, sun5i_gr8_pinctrl_match); static struct platform_driver sun5i_gr8_pinctrl_driver = { .probe = sun5i_gr8_pinctrl_probe, @@ -534,8 +533,4 @@ static struct platform_driver sun5i_gr8_pinctrl_driver = { .of_match_table = sun5i_gr8_pinctrl_match, }, }; -module_platform_driver(sun5i_gr8_pinctrl_driver); - -MODULE_AUTHOR("Mylene Josserand <mylene.josserand@free-electrons.com"); -MODULE_DESCRIPTION("NextThing GR8 pinctrl driver"); -MODULE_LICENSE("GPL"); +builtin_platform_driver(sun5i_gr8_pinctrl_driver); diff --git a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c index 862a096c5dba..fb30b86a97ee 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c @@ -10,7 +10,7 @@ * warranty of any kind, whether express or implied. */ -#include <linux/module.h> +#include <linux/init.h> #include <linux/platform_device.h> #include <linux/of.h> #include <linux/of_device.h> @@ -1035,7 +1035,6 @@ static const struct of_device_id sun4i_a10_pinctrl_match[] = { { .compatible = "allwinner,sun4i-a10-pinctrl", }, {} }; -MODULE_DEVICE_TABLE(of, sun4i_a10_pinctrl_match); static struct platform_driver sun4i_a10_pinctrl_driver = { .probe = sun4i_a10_pinctrl_probe, @@ -1044,8 +1043,4 @@ static struct platform_driver sun4i_a10_pinctrl_driver = { .of_match_table = sun4i_a10_pinctrl_match, }, }; -module_platform_driver(sun4i_a10_pinctrl_driver); - -MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com"); -MODULE_DESCRIPTION("Allwinner A10 pinctrl driver"); -MODULE_LICENSE("GPL"); +builtin_platform_driver(sun4i_a10_pinctrl_driver); diff --git a/drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c b/drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c index f9a3f8f446f7..a5b57fdff9e1 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun5i-a10s.c @@ -10,7 +10,7 @@ * warranty of any kind, whether express or implied. */ -#include <linux/module.h> +#include <linux/init.h> #include <linux/platform_device.h> #include <linux/of.h> #include <linux/of_device.h> @@ -674,7 +674,6 @@ static const struct of_device_id sun5i_a10s_pinctrl_match[] = { { .compatible = "allwinner,sun5i-a10s-pinctrl", }, {} }; -MODULE_DEVICE_TABLE(of, sun5i_a10s_pinctrl_match); static struct platform_driver sun5i_a10s_pinctrl_driver = { .probe = sun5i_a10s_pinctrl_probe, @@ -683,8 +682,4 @@ static struct platform_driver sun5i_a10s_pinctrl_driver = { .of_match_table = sun5i_a10s_pinctrl_match, }, }; -module_platform_driver(sun5i_a10s_pinctrl_driver); - -MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com"); -MODULE_DESCRIPTION("Allwinner A10s pinctrl driver"); -MODULE_LICENSE("GPL"); +builtin_platform_driver(sun5i_a10s_pinctrl_driver); diff --git a/drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c b/drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c index 2bb07b38834f..8575f3f6d3dd 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun5i-a13.c @@ -10,7 +10,7 @@ * warranty of any kind, whether express or implied. */ -#include <linux/module.h> +#include <linux/init.h> #include <linux/platform_device.h> #include <linux/of.h> #include <linux/of_device.h> @@ -392,7 +392,6 @@ static const struct of_device_id sun5i_a13_pinctrl_match[] = { { .compatible = "allwinner,sun5i-a13-pinctrl", }, {} }; -MODULE_DEVICE_TABLE(of, sun5i_a13_pinctrl_match); static struct platform_driver sun5i_a13_pinctrl_driver = { .probe = sun5i_a13_pinctrl_probe, @@ -401,8 +400,4 @@ static struct platform_driver sun5i_a13_pinctrl_driver = { .of_match_table = sun5i_a13_pinctrl_match, }, }; -module_platform_driver(sun5i_a13_pinctrl_driver); - -MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com"); -MODULE_DESCRIPTION("Allwinner A13 pinctrl driver"); -MODULE_LICENSE("GPL"); +builtin_platform_driver(sun5i_a13_pinctrl_driver); diff --git a/drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c b/drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c index d4bc4f0e8be0..a22bd88a1f03 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun6i-a31-r.c @@ -12,7 +12,7 @@ * warranty of any kind, whether express or implied. */ -#include <linux/module.h> +#include <linux/init.h> #include <linux/platform_device.h> #include <linux/of.h> #include <linux/of_device.h> @@ -136,7 +136,6 @@ static const struct of_device_id sun6i_a31_r_pinctrl_match[] = { { .compatible = "allwinner,sun6i-a31-r-pinctrl", }, {} }; -MODULE_DEVICE_TABLE(of, sun6i_a31_r_pinctrl_match); static struct platform_driver sun6i_a31_r_pinctrl_driver = { .probe = sun6i_a31_r_pinctrl_probe, @@ -145,9 +144,4 @@ static struct platform_driver sun6i_a31_r_pinctrl_driver = { .of_match_table = sun6i_a31_r_pinctrl_match, }, }; -module_platform_driver(sun6i_a31_r_pinctrl_driver); - -MODULE_AUTHOR("Boris Brezillon <boris.brezillon@free-electrons.com"); -MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com"); -MODULE_DESCRIPTION("Allwinner A31 R_PIO pinctrl driver"); -MODULE_LICENSE("GPL"); +builtin_platform_driver(sun6i_a31_r_pinctrl_driver); diff --git a/drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c b/drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c index a70b52957e24..9e58926bef37 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun6i-a31.c @@ -10,7 +10,7 @@ * warranty of any kind, whether express or implied. */ -#include <linux/module.h> +#include <linux/init.h> #include <linux/platform_device.h> #include <linux/of.h> #include <linux/of_device.h> @@ -934,7 +934,6 @@ static const struct of_device_id sun6i_a31_pinctrl_match[] = { { .compatible = "allwinner,sun6i-a31-pinctrl", }, {} }; -MODULE_DEVICE_TABLE(of, sun6i_a31_pinctrl_match); static struct platform_driver sun6i_a31_pinctrl_driver = { .probe = sun6i_a31_pinctrl_probe, @@ -943,8 +942,4 @@ static struct platform_driver sun6i_a31_pinctrl_driver = { .of_match_table = sun6i_a31_pinctrl_match, }, }; -module_platform_driver(sun6i_a31_pinctrl_driver); - -MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com"); -MODULE_DESCRIPTION("Allwinner A31 pinctrl driver"); -MODULE_LICENSE("GPL"); +builtin_platform_driver(sun6i_a31_pinctrl_driver); diff --git a/drivers/pinctrl/sunxi/pinctrl-sun6i-a31s.c b/drivers/pinctrl/sunxi/pinctrl-sun6i-a31s.c index e570d5c93ecc..231a746a5356 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun6i-a31s.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun6i-a31s.c @@ -11,7 +11,7 @@ * warranty of any kind, whether express or implied. */ -#include <linux/module.h> +#include <linux/init.h> #include <linux/platform_device.h> #include <linux/of.h> #include <linux/of_device.h> @@ -798,7 +798,6 @@ static const struct of_device_id sun6i_a31s_pinctrl_match[] = { { .compatible = "allwinner,sun6i-a31s-pinctrl", }, {} }; -MODULE_DEVICE_TABLE(of, sun6i_a31s_pinctrl_match); static struct platform_driver sun6i_a31s_pinctrl_driver = { .probe = sun6i_a31s_pinctrl_probe, @@ -807,8 +806,4 @@ static struct platform_driver sun6i_a31s_pinctrl_driver = { .of_match_table = sun6i_a31s_pinctrl_match, }, }; -module_platform_driver(sun6i_a31s_pinctrl_driver); - -MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); -MODULE_DESCRIPTION("Allwinner A31s pinctrl driver"); -MODULE_LICENSE("GPL"); +builtin_platform_driver(sun6i_a31s_pinctrl_driver); diff --git a/drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c b/drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c index 435ad30f45db..b6f4c68ffb39 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun7i-a20.c @@ -10,7 +10,7 @@ * warranty of any kind, whether express or implied. */ -#include <linux/module.h> +#include <linux/init.h> #include <linux/platform_device.h> #include <linux/of.h> #include <linux/of_device.h> @@ -1045,7 +1045,6 @@ static const struct of_device_id sun7i_a20_pinctrl_match[] = { { .compatible = "allwinner,sun7i-a20-pinctrl", }, {} }; -MODULE_DEVICE_TABLE(of, sun7i_a20_pinctrl_match); static struct platform_driver sun7i_a20_pinctrl_driver = { .probe = sun7i_a20_pinctrl_probe, @@ -1054,8 +1053,4 @@ static struct platform_driver sun7i_a20_pinctrl_driver = { .of_match_table = sun7i_a20_pinctrl_match, }, }; -module_platform_driver(sun7i_a20_pinctrl_driver); - -MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com"); -MODULE_DESCRIPTION("Allwinner A20 pinctrl driver"); -MODULE_LICENSE("GPL"); +builtin_platform_driver(sun7i_a20_pinctrl_driver); diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c index 056287635873..2292e05a397b 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23-r.c @@ -15,7 +15,7 @@ * warranty of any kind, whether express or implied. */ -#include <linux/module.h> +#include <linux/init.h> #include <linux/platform_device.h> #include <linux/of.h> #include <linux/of_device.h> @@ -123,7 +123,6 @@ static const struct of_device_id sun8i_a23_r_pinctrl_match[] = { { .compatible = "allwinner,sun8i-a23-r-pinctrl", }, {} }; -MODULE_DEVICE_TABLE(of, sun8i_a23_r_pinctrl_match); static struct platform_driver sun8i_a23_r_pinctrl_driver = { .probe = sun8i_a23_r_pinctrl_probe, @@ -132,10 +131,4 @@ static struct platform_driver sun8i_a23_r_pinctrl_driver = { .of_match_table = sun8i_a23_r_pinctrl_match, }, }; -module_platform_driver(sun8i_a23_r_pinctrl_driver); - -MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>"); -MODULE_AUTHOR("Boris Brezillon <boris.brezillon@free-electrons.com"); -MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com"); -MODULE_DESCRIPTION("Allwinner A23 R_PIO pinctrl driver"); -MODULE_LICENSE("GPL"); +builtin_platform_driver(sun8i_a23_r_pinctrl_driver); diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c index f9d661e5c14a..721b6935baf3 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c @@ -14,7 +14,7 @@ * warranty of any kind, whether express or implied. */ -#include <linux/module.h> +#include <linux/init.h> #include <linux/platform_device.h> #include <linux/of.h> #include <linux/of_device.h> @@ -575,7 +575,6 @@ static const struct of_device_id sun8i_a23_pinctrl_match[] = { { .compatible = "allwinner,sun8i-a23-pinctrl", }, {} }; -MODULE_DEVICE_TABLE(of, sun8i_a23_pinctrl_match); static struct platform_driver sun8i_a23_pinctrl_driver = { .probe = sun8i_a23_pinctrl_probe, @@ -584,9 +583,4 @@ static struct platform_driver sun8i_a23_pinctrl_driver = { .of_match_table = sun8i_a23_pinctrl_match, }, }; -module_platform_driver(sun8i_a23_pinctrl_driver); - -MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>"); -MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com"); -MODULE_DESCRIPTION("Allwinner A23 pinctrl driver"); -MODULE_LICENSE("GPL"); +builtin_platform_driver(sun8i_a23_pinctrl_driver); diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a33.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a33.c index 3131cac2b76f..ef1e0bef4099 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun8i-a33.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-a33.c @@ -12,7 +12,7 @@ * warranty of any kind, whether express or implied. */ -#include <linux/module.h> +#include <linux/init.h> #include <linux/platform_device.h> #include <linux/of.h> #include <linux/of_device.h> @@ -498,7 +498,6 @@ static const struct of_device_id sun8i_a33_pinctrl_match[] = { { .compatible = "allwinner,sun8i-a33-pinctrl", }, {} }; -MODULE_DEVICE_TABLE(of, sun8i_a33_pinctrl_match); static struct platform_driver sun8i_a33_pinctrl_driver = { .probe = sun8i_a33_pinctrl_probe, @@ -507,8 +506,4 @@ static struct platform_driver sun8i_a33_pinctrl_driver = { .of_match_table = sun8i_a33_pinctrl_match, }, }; -module_platform_driver(sun8i_a33_pinctrl_driver); - -MODULE_AUTHOR("Vishnu Patekar <vishnupatekar0510@gmail.com>"); -MODULE_DESCRIPTION("Allwinner a33 pinctrl driver"); -MODULE_LICENSE("GPL"); +builtin_platform_driver(sun8i_a33_pinctrl_driver); diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c index 90b973e15982..9aec1d2232dd 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c @@ -12,7 +12,7 @@ * warranty of any kind, whether express or implied. */ -#include <linux/module.h> +#include <linux/init.h> #include <linux/platform_device.h> #include <linux/of.h> #include <linux/of_device.h> @@ -587,7 +587,6 @@ static const struct of_device_id sun8i_a83t_pinctrl_match[] = { { .compatible = "allwinner,sun8i-a83t-pinctrl", }, {} }; -MODULE_DEVICE_TABLE(of, sun8i_a83t_pinctrl_match); static struct platform_driver sun8i_a83t_pinctrl_driver = { .probe = sun8i_a83t_pinctrl_probe, @@ -596,8 +595,4 @@ static struct platform_driver sun8i_a83t_pinctrl_driver = { .of_match_table = sun8i_a83t_pinctrl_match, }, }; -module_platform_driver(sun8i_a83t_pinctrl_driver); - -MODULE_AUTHOR("Vishnu Patekar <vishnupatekar0510@gmail.com>"); -MODULE_DESCRIPTION("Allwinner a83t pinctrl driver"); -MODULE_LICENSE("GPL"); +builtin_platform_driver(sun8i_a83t_pinctrl_driver); diff --git a/drivers/pinctrl/sunxi/pinctrl-sun9i-a80.c b/drivers/pinctrl/sunxi/pinctrl-sun9i-a80.c index 1b580ba76453..bc14e954d7a2 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun9i-a80.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun9i-a80.c @@ -10,7 +10,7 @@ * warranty of any kind, whether express or implied. */ -#include <linux/module.h> +#include <linux/init.h> #include <linux/platform_device.h> #include <linux/of.h> #include <linux/of_device.h> @@ -733,7 +733,6 @@ static const struct of_device_id sun9i_a80_pinctrl_match[] = { { .compatible = "allwinner,sun9i-a80-pinctrl", }, {} }; -MODULE_DEVICE_TABLE(of, sun9i_a80_pinctrl_match); static struct platform_driver sun9i_a80_pinctrl_driver = { .probe = sun9i_a80_pinctrl_probe, @@ -742,8 +741,4 @@ static struct platform_driver sun9i_a80_pinctrl_driver = { .of_match_table = sun9i_a80_pinctrl_match, }, }; -module_platform_driver(sun9i_a80_pinctrl_driver); - -MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>"); -MODULE_DESCRIPTION("Allwinner A80 pinctrl driver"); -MODULE_LICENSE("GPL"); +builtin_platform_driver(sun9i_a80_pinctrl_driver); diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index 0facbea5f465..0eb51e33cb1b 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -28,6 +28,8 @@ #include <linux/platform_device.h> #include <linux/slab.h> +#include <dt-bindings/pinctrl/sun4i-a10.h> + #include "../core.h" #include "pinctrl-sunxi.h" @@ -145,6 +147,171 @@ static int sunxi_pctrl_get_group_pins(struct pinctrl_dev *pctldev, return 0; } +static bool sunxi_pctrl_has_bias_prop(struct device_node *node) +{ + return of_find_property(node, "bias-pull-up", NULL) || + of_find_property(node, "bias-pull-down", NULL) || + of_find_property(node, "bias-disable", NULL) || + of_find_property(node, "allwinner,pull", NULL); +} + +static bool sunxi_pctrl_has_drive_prop(struct device_node *node) +{ + return of_find_property(node, "drive-strength", NULL) || + of_find_property(node, "allwinner,drive", NULL); +} + +static int sunxi_pctrl_parse_bias_prop(struct device_node *node) +{ + u32 val; + + /* Try the new style binding */ + if (of_find_property(node, "bias-pull-up", NULL)) + return PIN_CONFIG_BIAS_PULL_UP; + + if (of_find_property(node, "bias-pull-down", NULL)) + return PIN_CONFIG_BIAS_PULL_DOWN; + + if (of_find_property(node, "bias-disable", NULL)) + return PIN_CONFIG_BIAS_DISABLE; + + /* And fall back to the old binding */ + if (of_property_read_u32(node, "allwinner,pull", &val)) + return -EINVAL; + + switch (val) { + case SUN4I_PINCTRL_NO_PULL: + return PIN_CONFIG_BIAS_DISABLE; + case SUN4I_PINCTRL_PULL_UP: + return PIN_CONFIG_BIAS_PULL_UP; + case SUN4I_PINCTRL_PULL_DOWN: + return PIN_CONFIG_BIAS_PULL_DOWN; + } + + return -EINVAL; +} + +static int sunxi_pctrl_parse_drive_prop(struct device_node *node) +{ + u32 val; + + /* Try the new style binding */ + if (!of_property_read_u32(node, "drive-strength", &val)) { + /* We can't go below 10mA ... */ + if (val < 10) + return -EINVAL; + + /* ... and only up to 40 mA ... */ + if (val > 40) + val = 40; + + /* by steps of 10 mA */ + return rounddown(val, 10); + } + + /* And then fall back to the old binding */ + if (of_property_read_u32(node, "allwinner,drive", &val)) + return -EINVAL; + + return (val + 1) * 10; +} + +static const char *sunxi_pctrl_parse_function_prop(struct device_node *node) +{ + const char *function; + int ret; + + /* Try the generic binding */ + ret = of_property_read_string(node, "function", &function); + if (!ret) + return function; + + /* And fall back to our legacy one */ + ret = of_property_read_string(node, "allwinner,function", &function); + if (!ret) + return function; + + return NULL; +} + +static const char *sunxi_pctrl_find_pins_prop(struct device_node *node, + int *npins) +{ + int count; + + /* Try the generic binding */ + count = of_property_count_strings(node, "pins"); + if (count > 0) { + *npins = count; + return "pins"; + } + + /* And fall back to our legacy one */ + count = of_property_count_strings(node, "allwinner,pins"); + if (count > 0) { + *npins = count; + return "allwinner,pins"; + } + + return NULL; +} + +static unsigned long *sunxi_pctrl_build_pin_config(struct device_node *node, + unsigned int *len) +{ + unsigned long *pinconfig; + unsigned int configlen = 0, idx = 0; + int ret; + + if (sunxi_pctrl_has_drive_prop(node)) + configlen++; + if (sunxi_pctrl_has_bias_prop(node)) + configlen++; + + /* + * If we don't have any configuration, bail out + */ + if (!configlen) + return NULL; + + pinconfig = kzalloc(configlen * sizeof(*pinconfig), GFP_KERNEL); + if (!pinconfig) + return ERR_PTR(-ENOMEM); + + if (sunxi_pctrl_has_drive_prop(node)) { + int drive = sunxi_pctrl_parse_drive_prop(node); + if (drive < 0) { + ret = drive; + goto err_free; + } + + pinconfig[idx++] = pinconf_to_config_packed(PIN_CONFIG_DRIVE_STRENGTH, + drive); + } + + if (sunxi_pctrl_has_bias_prop(node)) { + int pull = sunxi_pctrl_parse_bias_prop(node); + int arg = 0; + if (pull < 0) { + ret = pull; + goto err_free; + } + + if (pull != PIN_CONFIG_BIAS_DISABLE) + arg = 1; /* hardware uses weak pull resistors */ + + pinconfig[idx++] = pinconf_to_config_packed(pull, arg); + } + + + *len = configlen; + return pinconfig; + +err_free: + kfree(pinconfig); + return ERR_PTR(ret); +} + static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node *node, struct pinctrl_map **map, @@ -153,38 +320,48 @@ static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev, struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); unsigned long *pinconfig; struct property *prop; - const char *function; + const char *function, *pin_prop; const char *group; - int ret, nmaps, i = 0; - u32 val; + int ret, npins, nmaps, configlen = 0, i = 0; *map = NULL; *num_maps = 0; - ret = of_property_read_string(node, "allwinner,function", &function); - if (ret) { - dev_err(pctl->dev, - "missing allwinner,function property in node %s\n", + function = sunxi_pctrl_parse_function_prop(node); + if (!function) { + dev_err(pctl->dev, "missing function property in node %s\n", node->name); return -EINVAL; } - nmaps = of_property_count_strings(node, "allwinner,pins") * 2; - if (nmaps < 0) { - dev_err(pctl->dev, - "missing allwinner,pins property in node %s\n", + pin_prop = sunxi_pctrl_find_pins_prop(node, &npins); + if (!pin_prop) { + dev_err(pctl->dev, "missing pins property in node %s\n", node->name); return -EINVAL; } + /* + * We have two maps for each pin: one for the function, one + * for the configuration (bias, strength, etc). + * + * We might be slightly overshooting, since we might not have + * any configuration. + */ + nmaps = npins * 2; *map = kmalloc(nmaps * sizeof(struct pinctrl_map), GFP_KERNEL); if (!*map) return -ENOMEM; - of_property_for_each_string(node, "allwinner,pins", prop, group) { + pinconfig = sunxi_pctrl_build_pin_config(node, &configlen); + if (IS_ERR(pinconfig)) { + ret = PTR_ERR(pinconfig); + goto err_free_map; + } + + of_property_for_each_string(node, pin_prop, prop, group) { struct sunxi_pinctrl_group *grp = sunxi_pinctrl_find_group_by_name(pctl, group); - int j = 0, configlen = 0; if (!grp) { dev_err(pctl->dev, "unknown pin %s", group); @@ -205,45 +382,31 @@ static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev, i++; - (*map)[i].type = PIN_MAP_TYPE_CONFIGS_GROUP; - (*map)[i].data.configs.group_or_pin = group; - - if (of_find_property(node, "allwinner,drive", NULL)) - configlen++; - if (of_find_property(node, "allwinner,pull", NULL)) - configlen++; - - pinconfig = kzalloc(configlen * sizeof(*pinconfig), GFP_KERNEL); - if (!pinconfig) { - kfree(*map); - return -ENOMEM; + if (pinconfig) { + (*map)[i].type = PIN_MAP_TYPE_CONFIGS_GROUP; + (*map)[i].data.configs.group_or_pin = group; + (*map)[i].data.configs.configs = pinconfig; + (*map)[i].data.configs.num_configs = configlen; + i++; } - - if (!of_property_read_u32(node, "allwinner,drive", &val)) { - u16 strength = (val + 1) * 10; - pinconfig[j++] = - pinconf_to_config_packed(PIN_CONFIG_DRIVE_STRENGTH, - strength); - } - - if (!of_property_read_u32(node, "allwinner,pull", &val)) { - enum pin_config_param pull = PIN_CONFIG_END; - if (val == 1) - pull = PIN_CONFIG_BIAS_PULL_UP; - else if (val == 2) - pull = PIN_CONFIG_BIAS_PULL_DOWN; - pinconfig[j++] = pinconf_to_config_packed(pull, 0); - } - - (*map)[i].data.configs.configs = pinconfig; - (*map)[i].data.configs.num_configs = configlen; - - i++; } - *num_maps = nmaps; + *num_maps = i; + + /* + * We know have the number of maps we need, we can resize our + * map array + */ + *map = krealloc(*map, i * sizeof(struct pinctrl_map), GFP_KERNEL); + if (!*map) + return -ENOMEM; return 0; + +err_free_map: + kfree(*map); + *map = NULL; + return ret; } static void sunxi_pctrl_dt_free_map(struct pinctrl_dev *pctldev, @@ -252,9 +415,17 @@ static void sunxi_pctrl_dt_free_map(struct pinctrl_dev *pctldev, { int i; - for (i = 0; i < num_maps; i++) { - if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP) - kfree(map[i].data.configs.configs); + /* pin config is never in the first map */ + for (i = 1; i < num_maps; i++) { + if (map[i].type != PIN_MAP_TYPE_CONFIGS_GROUP) + continue; + + /* + * All the maps share the same pin config, + * free only the first one we find. + */ + kfree(map[i].data.configs.configs); + break; } kfree(map); @@ -268,15 +439,91 @@ static const struct pinctrl_ops sunxi_pctrl_ops = { .get_group_pins = sunxi_pctrl_get_group_pins, }; +static int sunxi_pconf_reg(unsigned pin, enum pin_config_param param, + u32 *offset, u32 *shift, u32 *mask) +{ + switch (param) { + case PIN_CONFIG_DRIVE_STRENGTH: + *offset = sunxi_dlevel_reg(pin); + *shift = sunxi_dlevel_offset(pin); + *mask = DLEVEL_PINS_MASK; + break; + + case PIN_CONFIG_BIAS_PULL_UP: + case PIN_CONFIG_BIAS_PULL_DOWN: + case PIN_CONFIG_BIAS_DISABLE: + *offset = sunxi_pull_reg(pin); + *shift = sunxi_pull_offset(pin); + *mask = PULL_PINS_MASK; + break; + + default: + return -ENOTSUPP; + } + + return 0; +} + +static int sunxi_pconf_get(struct pinctrl_dev *pctldev, unsigned pin, + unsigned long *config) +{ + struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + enum pin_config_param param = pinconf_to_config_param(*config); + u32 offset, shift, mask, val; + u16 arg; + int ret; + + pin -= pctl->desc->pin_base; + + ret = sunxi_pconf_reg(pin, param, &offset, &shift, &mask); + if (ret < 0) + return ret; + + val = (readl(pctl->membase + offset) >> shift) & mask; + + switch (pinconf_to_config_param(*config)) { + case PIN_CONFIG_DRIVE_STRENGTH: + arg = (val + 1) * 10; + break; + + case PIN_CONFIG_BIAS_PULL_UP: + if (val != SUN4I_PINCTRL_PULL_UP) + return -EINVAL; + arg = 1; /* hardware is weak pull-up */ + break; + + case PIN_CONFIG_BIAS_PULL_DOWN: + if (val != SUN4I_PINCTRL_PULL_DOWN) + return -EINVAL; + arg = 1; /* hardware is weak pull-down */ + break; + + case PIN_CONFIG_BIAS_DISABLE: + if (val != SUN4I_PINCTRL_NO_PULL) + return -EINVAL; + arg = 0; + break; + + default: + /* sunxi_pconf_reg should catch anything unsupported */ + WARN_ON(1); + return -ENOTSUPP; + } + + *config = pinconf_to_config_packed(param, arg); + + return 0; +} + static int sunxi_pconf_group_get(struct pinctrl_dev *pctldev, unsigned group, unsigned long *config) { struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + struct sunxi_pinctrl_group *g = &pctl->groups[group]; - *config = pctl->groups[group].config; - - return 0; + /* We only support 1 pin per group. Chain it to the pin callback */ + return sunxi_pconf_get(pctldev, g->pin, config); } static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev, @@ -286,23 +533,27 @@ static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev, { struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); struct sunxi_pinctrl_group *g = &pctl->groups[group]; - unsigned long flags; unsigned pin = g->pin - pctl->desc->pin_base; - u32 val, mask; - u16 strength; - u8 dlevel; int i; - spin_lock_irqsave(&pctl->lock, flags); - for (i = 0; i < num_configs; i++) { - switch (pinconf_to_config_param(configs[i])) { + enum pin_config_param param; + unsigned long flags; + u32 offset, shift, mask, reg; + u16 arg, val; + int ret; + + param = pinconf_to_config_param(configs[i]); + arg = pinconf_to_config_argument(configs[i]); + + ret = sunxi_pconf_reg(pin, param, &offset, &shift, &mask); + if (ret < 0) + return ret; + + switch (param) { case PIN_CONFIG_DRIVE_STRENGTH: - strength = pinconf_to_config_argument(configs[i]); - if (strength > 40) { - spin_unlock_irqrestore(&pctl->lock, flags); + if (arg < 10 || arg > 40) return -EINVAL; - } /* * We convert from mA to what the register expects: * 0: 10mA @@ -310,38 +561,40 @@ static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev, * 2: 30mA * 3: 40mA */ - dlevel = strength / 10 - 1; - val = readl(pctl->membase + sunxi_dlevel_reg(pin)); - mask = DLEVEL_PINS_MASK << sunxi_dlevel_offset(pin); - writel((val & ~mask) - | dlevel << sunxi_dlevel_offset(pin), - pctl->membase + sunxi_dlevel_reg(pin)); + val = arg / 10 - 1; + break; + case PIN_CONFIG_BIAS_DISABLE: + val = 0; break; case PIN_CONFIG_BIAS_PULL_UP: - val = readl(pctl->membase + sunxi_pull_reg(pin)); - mask = PULL_PINS_MASK << sunxi_pull_offset(pin); - writel((val & ~mask) | 1 << sunxi_pull_offset(pin), - pctl->membase + sunxi_pull_reg(pin)); + if (arg == 0) + return -EINVAL; + val = 1; break; case PIN_CONFIG_BIAS_PULL_DOWN: - val = readl(pctl->membase + sunxi_pull_reg(pin)); - mask = PULL_PINS_MASK << sunxi_pull_offset(pin); - writel((val & ~mask) | 2 << sunxi_pull_offset(pin), - pctl->membase + sunxi_pull_reg(pin)); + if (arg == 0) + return -EINVAL; + val = 2; break; default: - break; + /* sunxi_pconf_reg should catch anything unsupported */ + WARN_ON(1); + return -ENOTSUPP; } - /* cache the config value */ - g->config = configs[i]; - } /* for each config */ - spin_unlock_irqrestore(&pctl->lock, flags); + spin_lock_irqsave(&pctl->lock, flags); + reg = readl(pctl->membase + offset); + reg &= ~(mask << shift); + writel(reg | val << shift, pctl->membase + offset); + spin_unlock_irqrestore(&pctl->lock, flags); + } /* for each config */ return 0; } static const struct pinconf_ops sunxi_pconf_ops = { + .is_generic = true, + .pin_config_get = sunxi_pconf_get, .pin_config_group_get = sunxi_pconf_group_get, .pin_config_group_set = sunxi_pconf_group_set, }; @@ -870,6 +1123,91 @@ static int sunxi_pinctrl_build_state(struct platform_device *pdev) return 0; } +static int sunxi_pinctrl_get_debounce_div(struct clk *clk, int freq, int *diff) +{ + unsigned long clock = clk_get_rate(clk); + unsigned int best_diff, best_div; + int i; + + best_diff = abs(freq - clock); + best_div = 0; + + for (i = 1; i < 8; i++) { + int cur_diff = abs(freq - (clock >> i)); + + if (cur_diff < best_diff) { + best_diff = cur_diff; + best_div = i; + } + } + + *diff = best_diff; + return best_div; +} + +static int sunxi_pinctrl_setup_debounce(struct sunxi_pinctrl *pctl, + struct device_node *node) +{ + unsigned int hosc_diff, losc_diff; + unsigned int hosc_div, losc_div; + struct clk *hosc, *losc; + u8 div, src; + int i, ret; + + /* Deal with old DTs that didn't have the oscillators */ + if (of_count_phandle_with_args(node, "clocks", "#clock-cells") != 3) + return 0; + + /* If we don't have any setup, bail out */ + if (!of_find_property(node, "input-debounce", NULL)) + return 0; + + losc = devm_clk_get(pctl->dev, "losc"); + if (IS_ERR(losc)) + return PTR_ERR(losc); + + hosc = devm_clk_get(pctl->dev, "hosc"); + if (IS_ERR(hosc)) + return PTR_ERR(hosc); + + for (i = 0; i < pctl->desc->irq_banks; i++) { + unsigned long debounce_freq; + u32 debounce; + + ret = of_property_read_u32_index(node, "input-debounce", + i, &debounce); + if (ret) + return ret; + + if (!debounce) + continue; + + debounce_freq = DIV_ROUND_CLOSEST(USEC_PER_SEC, debounce); + losc_div = sunxi_pinctrl_get_debounce_div(losc, + debounce_freq, + &losc_diff); + + hosc_div = sunxi_pinctrl_get_debounce_div(hosc, + debounce_freq, + &hosc_diff); + + if (hosc_diff < losc_diff) { + div = hosc_div; + src = 1; + } else { + div = losc_div; + src = 0; + } + + writel(src | div << 4, + pctl->membase + + sunxi_irq_debounce_reg_from_bank(i, + pctl->desc->irq_bank_base)); + } + + return 0; +} + int sunxi_pinctrl_init(struct platform_device *pdev, const struct sunxi_pinctrl_desc *desc) { @@ -1032,6 +1370,8 @@ int sunxi_pinctrl_init(struct platform_device *pdev, pctl); } + sunxi_pinctrl_setup_debounce(pctl, node); + dev_info(&pdev->dev, "initialized sunXi PIO driver\n"); return 0; diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h b/drivers/pinctrl/sunxi/pinctrl-sunxi.h index 0afce1ab12d0..f78a44a03189 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h @@ -69,6 +69,8 @@ #define IRQ_STATUS_IRQ_BITS 1 #define IRQ_STATUS_IRQ_MASK ((1 << IRQ_STATUS_IRQ_BITS) - 1) +#define IRQ_DEBOUNCE_REG 0x218 + #define IRQ_MEM_SIZE 0x20 #define IRQ_EDGE_RISING 0x00 @@ -109,7 +111,6 @@ struct sunxi_pinctrl_function { struct sunxi_pinctrl_group { const char *name; - unsigned long config; unsigned pin; }; @@ -266,6 +267,11 @@ static inline u32 sunxi_irq_ctrl_offset(u16 irq) return irq_num * IRQ_CTRL_IRQ_BITS; } +static inline u32 sunxi_irq_debounce_reg_from_bank(u8 bank, unsigned bank_base) +{ + return IRQ_DEBOUNCE_REG + (bank_base + bank) * IRQ_MEM_SIZE; +} + static inline u32 sunxi_irq_status_reg_from_bank(u8 bank, unsigned bank_base) { return IRQ_STATUS_REG + (bank_base + bank) * IRQ_MEM_SIZE; diff --git a/drivers/pinctrl/vt8500/pinctrl-vt8500.c b/drivers/pinctrl/vt8500/pinctrl-vt8500.c index ca946b3dbdb4..767f340d6b11 100644 --- a/drivers/pinctrl/vt8500/pinctrl-vt8500.c +++ b/drivers/pinctrl/vt8500/pinctrl-vt8500.c @@ -14,7 +14,7 @@ */ #include <linux/io.h> -#include <linux/module.h> +#include <linux/init.h> #include <linux/pinctrl/pinctrl.h> #include <linux/platform_device.h> #include <linux/slab.h> @@ -473,11 +473,6 @@ static int vt8500_pinctrl_probe(struct platform_device *pdev) return wmt_pinctrl_probe(pdev, data); } -static int vt8500_pinctrl_remove(struct platform_device *pdev) -{ - return wmt_pinctrl_remove(pdev); -} - static const struct of_device_id wmt_pinctrl_of_match[] = { { .compatible = "via,vt8500-pinctrl" }, { /* sentinel */ }, @@ -485,16 +480,10 @@ static const struct of_device_id wmt_pinctrl_of_match[] = { static struct platform_driver wmt_pinctrl_driver = { .probe = vt8500_pinctrl_probe, - .remove = vt8500_pinctrl_remove, .driver = { .name = "pinctrl-vt8500", .of_match_table = wmt_pinctrl_of_match, + .suppress_bind_attrs = true, }, }; - -module_platform_driver(wmt_pinctrl_driver); - -MODULE_AUTHOR("Tony Prisk <linux@prisktech.co.nz>"); -MODULE_DESCRIPTION("VIA VT8500 Pincontrol driver"); -MODULE_LICENSE("GPL v2"); -MODULE_DEVICE_TABLE(of, wmt_pinctrl_of_match); +builtin_platform_driver(wmt_pinctrl_driver); diff --git a/drivers/pinctrl/vt8500/pinctrl-wm8505.c b/drivers/pinctrl/vt8500/pinctrl-wm8505.c index 626fc7ec0174..a56fdbd87e42 100644 --- a/drivers/pinctrl/vt8500/pinctrl-wm8505.c +++ b/drivers/pinctrl/vt8500/pinctrl-wm8505.c @@ -14,7 +14,7 @@ */ #include <linux/io.h> -#include <linux/module.h> +#include <linux/init.h> #include <linux/pinctrl/pinctrl.h> #include <linux/platform_device.h> #include <linux/slab.h> @@ -504,11 +504,6 @@ static int wm8505_pinctrl_probe(struct platform_device *pdev) return wmt_pinctrl_probe(pdev, data); } -static int wm8505_pinctrl_remove(struct platform_device *pdev) -{ - return wmt_pinctrl_remove(pdev); -} - static const struct of_device_id wmt_pinctrl_of_match[] = { { .compatible = "wm,wm8505-pinctrl" }, { /* sentinel */ }, @@ -516,16 +511,10 @@ static const struct of_device_id wmt_pinctrl_of_match[] = { static struct platform_driver wmt_pinctrl_driver = { .probe = wm8505_pinctrl_probe, - .remove = wm8505_pinctrl_remove, .driver = { .name = "pinctrl-wm8505", .of_match_table = wmt_pinctrl_of_match, + .suppress_bind_attrs = true, }, }; - -module_platform_driver(wmt_pinctrl_driver); - -MODULE_AUTHOR("Tony Prisk <linux@prisktech.co.nz>"); -MODULE_DESCRIPTION("Wondermedia WM8505 Pincontrol driver"); -MODULE_LICENSE("GPL v2"); -MODULE_DEVICE_TABLE(of, wmt_pinctrl_of_match); +builtin_platform_driver(wmt_pinctrl_driver); diff --git a/drivers/pinctrl/vt8500/pinctrl-wm8650.c b/drivers/pinctrl/vt8500/pinctrl-wm8650.c index 8953aba8bfc2..270dd491f5a1 100644 --- a/drivers/pinctrl/vt8500/pinctrl-wm8650.c +++ b/drivers/pinctrl/vt8500/pinctrl-wm8650.c @@ -14,7 +14,7 @@ */ #include <linux/io.h> -#include <linux/module.h> +#include <linux/init.h> #include <linux/pinctrl/pinctrl.h> #include <linux/platform_device.h> #include <linux/slab.h> @@ -342,11 +342,6 @@ static int wm8650_pinctrl_probe(struct platform_device *pdev) return wmt_pinctrl_probe(pdev, data); } -static int wm8650_pinctrl_remove(struct platform_device *pdev) -{ - return wmt_pinctrl_remove(pdev); -} - static const struct of_device_id wmt_pinctrl_of_match[] = { { .compatible = "wm,wm8650-pinctrl" }, { /* sentinel */ }, @@ -354,16 +349,10 @@ static const struct of_device_id wmt_pinctrl_of_match[] = { static struct platform_driver wmt_pinctrl_driver = { .probe = wm8650_pinctrl_probe, - .remove = wm8650_pinctrl_remove, .driver = { .name = "pinctrl-wm8650", .of_match_table = wmt_pinctrl_of_match, + .suppress_bind_attrs = true, }, }; - -module_platform_driver(wmt_pinctrl_driver); - -MODULE_AUTHOR("Tony Prisk <linux@prisktech.co.nz>"); -MODULE_DESCRIPTION("Wondermedia WM8650 Pincontrol driver"); -MODULE_LICENSE("GPL v2"); -MODULE_DEVICE_TABLE(of, wmt_pinctrl_of_match); +builtin_platform_driver(wmt_pinctrl_driver); diff --git a/drivers/pinctrl/vt8500/pinctrl-wm8750.c b/drivers/pinctrl/vt8500/pinctrl-wm8750.c index c79053d430db..74f7b3a18f3a 100644 --- a/drivers/pinctrl/vt8500/pinctrl-wm8750.c +++ b/drivers/pinctrl/vt8500/pinctrl-wm8750.c @@ -14,7 +14,7 @@ */ #include <linux/io.h> -#include <linux/module.h> +#include <linux/init.h> #include <linux/pinctrl/pinctrl.h> #include <linux/platform_device.h> #include <linux/slab.h> @@ -381,11 +381,6 @@ static int wm8750_pinctrl_probe(struct platform_device *pdev) return wmt_pinctrl_probe(pdev, data); } -static int wm8750_pinctrl_remove(struct platform_device *pdev) -{ - return wmt_pinctrl_remove(pdev); -} - static const struct of_device_id wmt_pinctrl_of_match[] = { { .compatible = "wm,wm8750-pinctrl" }, { /* sentinel */ }, @@ -393,16 +388,10 @@ static const struct of_device_id wmt_pinctrl_of_match[] = { static struct platform_driver wmt_pinctrl_driver = { .probe = wm8750_pinctrl_probe, - .remove = wm8750_pinctrl_remove, .driver = { .name = "pinctrl-wm8750", .of_match_table = wmt_pinctrl_of_match, + .suppress_bind_attrs = true, }, }; - -module_platform_driver(wmt_pinctrl_driver); - -MODULE_AUTHOR("Tony Prisk <linux@prisktech.co.nz>"); -MODULE_DESCRIPTION("Wondermedia WM8750 Pincontrol driver"); -MODULE_LICENSE("GPL v2"); -MODULE_DEVICE_TABLE(of, wmt_pinctrl_of_match); +builtin_platform_driver(wmt_pinctrl_driver); diff --git a/drivers/pinctrl/vt8500/pinctrl-wm8850.c b/drivers/pinctrl/vt8500/pinctrl-wm8850.c index f232b163c735..45792aa7a06e 100644 --- a/drivers/pinctrl/vt8500/pinctrl-wm8850.c +++ b/drivers/pinctrl/vt8500/pinctrl-wm8850.c @@ -14,7 +14,7 @@ */ #include <linux/io.h> -#include <linux/module.h> +#include <linux/init.h> #include <linux/pinctrl/pinctrl.h> #include <linux/platform_device.h> #include <linux/slab.h> @@ -360,11 +360,6 @@ static int wm8850_pinctrl_probe(struct platform_device *pdev) return wmt_pinctrl_probe(pdev, data); } -static int wm8850_pinctrl_remove(struct platform_device *pdev) -{ - return wmt_pinctrl_remove(pdev); -} - static const struct of_device_id wmt_pinctrl_of_match[] = { { .compatible = "wm,wm8850-pinctrl" }, { /* sentinel */ }, @@ -372,16 +367,10 @@ static const struct of_device_id wmt_pinctrl_of_match[] = { static struct platform_driver wmt_pinctrl_driver = { .probe = wm8850_pinctrl_probe, - .remove = wm8850_pinctrl_remove, .driver = { .name = "pinctrl-wm8850", .of_match_table = wmt_pinctrl_of_match, + .suppress_bind_attrs = true, }, }; - -module_platform_driver(wmt_pinctrl_driver); - -MODULE_AUTHOR("Tony Prisk <linux@prisktech.co.nz>"); -MODULE_DESCRIPTION("Wondermedia WM8850 Pincontrol driver"); -MODULE_LICENSE("GPL v2"); -MODULE_DEVICE_TABLE(of, wmt_pinctrl_of_match); +builtin_platform_driver(wmt_pinctrl_driver); diff --git a/drivers/pinctrl/vt8500/pinctrl-wmt.c b/drivers/pinctrl/vt8500/pinctrl-wmt.c index cbc638631678..270ca2a47a8c 100644 --- a/drivers/pinctrl/vt8500/pinctrl-wmt.c +++ b/drivers/pinctrl/vt8500/pinctrl-wmt.c @@ -18,7 +18,6 @@ #include <linux/interrupt.h> #include <linux/io.h> #include <linux/irq.h> -#include <linux/module.h> #include <linux/of.h> #include <linux/of_irq.h> #include <linux/pinctrl/consumer.h> @@ -608,12 +607,3 @@ fail_range: gpiochip_remove(&data->gpio_chip); return err; } - -int wmt_pinctrl_remove(struct platform_device *pdev) -{ - struct wmt_pinctrl_data *data = platform_get_drvdata(pdev); - - gpiochip_remove(&data->gpio_chip); - - return 0; -} diff --git a/drivers/pinctrl/vt8500/pinctrl-wmt.h b/drivers/pinctrl/vt8500/pinctrl-wmt.h index 41f5f2deb5d6..885613396fe7 100644 --- a/drivers/pinctrl/vt8500/pinctrl-wmt.h +++ b/drivers/pinctrl/vt8500/pinctrl-wmt.h @@ -76,4 +76,3 @@ struct wmt_pinctrl_data { int wmt_pinctrl_probe(struct platform_device *pdev, struct wmt_pinctrl_data *data); -int wmt_pinctrl_remove(struct platform_device *pdev); |