162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Driver for BCM6358 GPIO unit (pinctrl + GPIO) 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com> 662306a36Sopenharmony_ci * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com> 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/bits.h> 1062306a36Sopenharmony_ci#include <linux/gpio/driver.h> 1162306a36Sopenharmony_ci#include <linux/kernel.h> 1262306a36Sopenharmony_ci#include <linux/of.h> 1362306a36Sopenharmony_ci#include <linux/pinctrl/pinmux.h> 1462306a36Sopenharmony_ci#include <linux/platform_device.h> 1562306a36Sopenharmony_ci#include <linux/regmap.h> 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#include "../pinctrl-utils.h" 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#include "pinctrl-bcm63xx.h" 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#define BCM6358_NUM_GPIOS 40 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci#define BCM6358_MODE_REG 0x18 2462306a36Sopenharmony_ci#define BCM6358_MODE_MUX_NONE 0 2562306a36Sopenharmony_ci#define BCM6358_MODE_MUX_EBI_CS BIT(5) 2662306a36Sopenharmony_ci#define BCM6358_MODE_MUX_UART1 BIT(6) 2762306a36Sopenharmony_ci#define BCM6358_MODE_MUX_SPI_CS BIT(7) 2862306a36Sopenharmony_ci#define BCM6358_MODE_MUX_ASYNC_MODEM BIT(8) 2962306a36Sopenharmony_ci#define BCM6358_MODE_MUX_LEGACY_LED BIT(9) 3062306a36Sopenharmony_ci#define BCM6358_MODE_MUX_SERIAL_LED BIT(10) 3162306a36Sopenharmony_ci#define BCM6358_MODE_MUX_LED BIT(11) 3262306a36Sopenharmony_ci#define BCM6358_MODE_MUX_UTOPIA BIT(12) 3362306a36Sopenharmony_ci#define BCM6358_MODE_MUX_CLKRST BIT(13) 3462306a36Sopenharmony_ci#define BCM6358_MODE_MUX_PWM_SYN_CLK BIT(14) 3562306a36Sopenharmony_ci#define BCM6358_MODE_MUX_SYS_IRQ BIT(15) 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_cistruct bcm6358_pingroup { 3862306a36Sopenharmony_ci struct pingroup grp; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci const uint16_t mode_val; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci /* non-GPIO function muxes require the gpio direction to be set */ 4362306a36Sopenharmony_ci const uint16_t direction; 4462306a36Sopenharmony_ci}; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_cistruct bcm6358_function { 4762306a36Sopenharmony_ci const char *name; 4862306a36Sopenharmony_ci const char * const *groups; 4962306a36Sopenharmony_ci const unsigned num_groups; 5062306a36Sopenharmony_ci}; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_cistruct bcm6358_priv { 5362306a36Sopenharmony_ci struct regmap_field *overlays; 5462306a36Sopenharmony_ci}; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci#define BCM6358_GPIO_PIN(a, b, bit1, bit2, bit3) \ 5762306a36Sopenharmony_ci { \ 5862306a36Sopenharmony_ci .number = a, \ 5962306a36Sopenharmony_ci .name = b, \ 6062306a36Sopenharmony_ci .drv_data = (void *)(BCM6358_MODE_MUX_##bit1 | \ 6162306a36Sopenharmony_ci BCM6358_MODE_MUX_##bit2 | \ 6262306a36Sopenharmony_ci BCM6358_MODE_MUX_##bit3), \ 6362306a36Sopenharmony_ci } 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_cistatic const struct pinctrl_pin_desc bcm6358_pins[] = { 6662306a36Sopenharmony_ci BCM6358_GPIO_PIN(0, "gpio0", LED, NONE, NONE), 6762306a36Sopenharmony_ci BCM6358_GPIO_PIN(1, "gpio1", LED, NONE, NONE), 6862306a36Sopenharmony_ci BCM6358_GPIO_PIN(2, "gpio2", LED, NONE, NONE), 6962306a36Sopenharmony_ci BCM6358_GPIO_PIN(3, "gpio3", LED, NONE, NONE), 7062306a36Sopenharmony_ci PINCTRL_PIN(4, "gpio4"), 7162306a36Sopenharmony_ci BCM6358_GPIO_PIN(5, "gpio5", SYS_IRQ, NONE, NONE), 7262306a36Sopenharmony_ci BCM6358_GPIO_PIN(6, "gpio6", SERIAL_LED, NONE, NONE), 7362306a36Sopenharmony_ci BCM6358_GPIO_PIN(7, "gpio7", SERIAL_LED, NONE, NONE), 7462306a36Sopenharmony_ci BCM6358_GPIO_PIN(8, "gpio8", PWM_SYN_CLK, NONE, NONE), 7562306a36Sopenharmony_ci BCM6358_GPIO_PIN(9, "gpio09", LEGACY_LED, NONE, NONE), 7662306a36Sopenharmony_ci BCM6358_GPIO_PIN(10, "gpio10", LEGACY_LED, NONE, NONE), 7762306a36Sopenharmony_ci BCM6358_GPIO_PIN(11, "gpio11", LEGACY_LED, NONE, NONE), 7862306a36Sopenharmony_ci BCM6358_GPIO_PIN(12, "gpio12", LEGACY_LED, ASYNC_MODEM, UTOPIA), 7962306a36Sopenharmony_ci BCM6358_GPIO_PIN(13, "gpio13", LEGACY_LED, ASYNC_MODEM, UTOPIA), 8062306a36Sopenharmony_ci BCM6358_GPIO_PIN(14, "gpio14", LEGACY_LED, ASYNC_MODEM, UTOPIA), 8162306a36Sopenharmony_ci BCM6358_GPIO_PIN(15, "gpio15", LEGACY_LED, ASYNC_MODEM, UTOPIA), 8262306a36Sopenharmony_ci PINCTRL_PIN(16, "gpio16"), 8362306a36Sopenharmony_ci PINCTRL_PIN(17, "gpio17"), 8462306a36Sopenharmony_ci PINCTRL_PIN(18, "gpio18"), 8562306a36Sopenharmony_ci PINCTRL_PIN(19, "gpio19"), 8662306a36Sopenharmony_ci PINCTRL_PIN(20, "gpio20"), 8762306a36Sopenharmony_ci PINCTRL_PIN(21, "gpio21"), 8862306a36Sopenharmony_ci BCM6358_GPIO_PIN(22, "gpio22", UTOPIA, NONE, NONE), 8962306a36Sopenharmony_ci BCM6358_GPIO_PIN(23, "gpio23", UTOPIA, NONE, NONE), 9062306a36Sopenharmony_ci BCM6358_GPIO_PIN(24, "gpio24", UTOPIA, NONE, NONE), 9162306a36Sopenharmony_ci BCM6358_GPIO_PIN(25, "gpio25", UTOPIA, NONE, NONE), 9262306a36Sopenharmony_ci BCM6358_GPIO_PIN(26, "gpio26", UTOPIA, NONE, NONE), 9362306a36Sopenharmony_ci BCM6358_GPIO_PIN(27, "gpio27", UTOPIA, NONE, NONE), 9462306a36Sopenharmony_ci BCM6358_GPIO_PIN(28, "gpio28", UTOPIA, UART1, NONE), 9562306a36Sopenharmony_ci BCM6358_GPIO_PIN(29, "gpio29", UTOPIA, UART1, NONE), 9662306a36Sopenharmony_ci BCM6358_GPIO_PIN(30, "gpio30", UTOPIA, UART1, EBI_CS), 9762306a36Sopenharmony_ci BCM6358_GPIO_PIN(31, "gpio31", UTOPIA, UART1, EBI_CS), 9862306a36Sopenharmony_ci BCM6358_GPIO_PIN(32, "gpio32", SPI_CS, NONE, NONE), 9962306a36Sopenharmony_ci BCM6358_GPIO_PIN(33, "gpio33", SPI_CS, NONE, NONE), 10062306a36Sopenharmony_ci PINCTRL_PIN(34, "gpio34"), 10162306a36Sopenharmony_ci PINCTRL_PIN(35, "gpio35"), 10262306a36Sopenharmony_ci PINCTRL_PIN(36, "gpio36"), 10362306a36Sopenharmony_ci PINCTRL_PIN(37, "gpio37"), 10462306a36Sopenharmony_ci PINCTRL_PIN(38, "gpio38"), 10562306a36Sopenharmony_ci PINCTRL_PIN(39, "gpio39"), 10662306a36Sopenharmony_ci}; 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_cistatic unsigned ebi_cs_grp_pins[] = { 30, 31 }; 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_cistatic unsigned uart1_grp_pins[] = { 28, 29, 30, 31 }; 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_cistatic unsigned spi_cs_grp_pins[] = { 32, 33 }; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_cistatic unsigned async_modem_grp_pins[] = { 12, 13, 14, 15 }; 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_cistatic unsigned serial_led_grp_pins[] = { 6, 7 }; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_cistatic unsigned legacy_led_grp_pins[] = { 9, 10, 11, 12, 13, 14, 15 }; 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_cistatic unsigned led_grp_pins[] = { 0, 1, 2, 3 }; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_cistatic unsigned utopia_grp_pins[] = { 12362306a36Sopenharmony_ci 12, 13, 14, 15, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 12462306a36Sopenharmony_ci}; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_cistatic unsigned pwm_syn_clk_grp_pins[] = { 8 }; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_cistatic unsigned sys_irq_grp_pins[] = { 5 }; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci#define BCM6358_GPIO_MUX_GROUP(n, bit, dir) \ 13162306a36Sopenharmony_ci { \ 13262306a36Sopenharmony_ci .grp = BCM_PIN_GROUP(n), \ 13362306a36Sopenharmony_ci .mode_val = BCM6358_MODE_MUX_##bit, \ 13462306a36Sopenharmony_ci .direction = dir, \ 13562306a36Sopenharmony_ci } 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_cistatic const struct bcm6358_pingroup bcm6358_groups[] = { 13862306a36Sopenharmony_ci BCM6358_GPIO_MUX_GROUP(ebi_cs_grp, EBI_CS, 0x3), 13962306a36Sopenharmony_ci BCM6358_GPIO_MUX_GROUP(uart1_grp, UART1, 0x2), 14062306a36Sopenharmony_ci BCM6358_GPIO_MUX_GROUP(spi_cs_grp, SPI_CS, 0x6), 14162306a36Sopenharmony_ci BCM6358_GPIO_MUX_GROUP(async_modem_grp, ASYNC_MODEM, 0x6), 14262306a36Sopenharmony_ci BCM6358_GPIO_MUX_GROUP(legacy_led_grp, LEGACY_LED, 0x7f), 14362306a36Sopenharmony_ci BCM6358_GPIO_MUX_GROUP(serial_led_grp, SERIAL_LED, 0x3), 14462306a36Sopenharmony_ci BCM6358_GPIO_MUX_GROUP(led_grp, LED, 0xf), 14562306a36Sopenharmony_ci BCM6358_GPIO_MUX_GROUP(utopia_grp, UTOPIA, 0x000f), 14662306a36Sopenharmony_ci BCM6358_GPIO_MUX_GROUP(pwm_syn_clk_grp, PWM_SYN_CLK, 0x1), 14762306a36Sopenharmony_ci BCM6358_GPIO_MUX_GROUP(sys_irq_grp, SYS_IRQ, 0x1), 14862306a36Sopenharmony_ci}; 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_cistatic const char * const ebi_cs_groups[] = { 15162306a36Sopenharmony_ci "ebi_cs_grp" 15262306a36Sopenharmony_ci}; 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_cistatic const char * const uart1_groups[] = { 15562306a36Sopenharmony_ci "uart1_grp" 15662306a36Sopenharmony_ci}; 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_cistatic const char * const spi_cs_2_3_groups[] = { 15962306a36Sopenharmony_ci "spi_cs_2_3_grp" 16062306a36Sopenharmony_ci}; 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_cistatic const char * const async_modem_groups[] = { 16362306a36Sopenharmony_ci "async_modem_grp" 16462306a36Sopenharmony_ci}; 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_cistatic const char * const legacy_led_groups[] = { 16762306a36Sopenharmony_ci "legacy_led_grp", 16862306a36Sopenharmony_ci}; 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_cistatic const char * const serial_led_groups[] = { 17162306a36Sopenharmony_ci "serial_led_grp", 17262306a36Sopenharmony_ci}; 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_cistatic const char * const led_groups[] = { 17562306a36Sopenharmony_ci "led_grp", 17662306a36Sopenharmony_ci}; 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_cistatic const char * const clkrst_groups[] = { 17962306a36Sopenharmony_ci "clkrst_grp", 18062306a36Sopenharmony_ci}; 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_cistatic const char * const pwm_syn_clk_groups[] = { 18362306a36Sopenharmony_ci "pwm_syn_clk_grp", 18462306a36Sopenharmony_ci}; 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_cistatic const char * const sys_irq_groups[] = { 18762306a36Sopenharmony_ci "sys_irq_grp", 18862306a36Sopenharmony_ci}; 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci#define BCM6358_FUN(n) \ 19162306a36Sopenharmony_ci { \ 19262306a36Sopenharmony_ci .name = #n, \ 19362306a36Sopenharmony_ci .groups = n##_groups, \ 19462306a36Sopenharmony_ci .num_groups = ARRAY_SIZE(n##_groups), \ 19562306a36Sopenharmony_ci } 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_cistatic const struct bcm6358_function bcm6358_funcs[] = { 19862306a36Sopenharmony_ci BCM6358_FUN(ebi_cs), 19962306a36Sopenharmony_ci BCM6358_FUN(uart1), 20062306a36Sopenharmony_ci BCM6358_FUN(spi_cs_2_3), 20162306a36Sopenharmony_ci BCM6358_FUN(async_modem), 20262306a36Sopenharmony_ci BCM6358_FUN(legacy_led), 20362306a36Sopenharmony_ci BCM6358_FUN(serial_led), 20462306a36Sopenharmony_ci BCM6358_FUN(led), 20562306a36Sopenharmony_ci BCM6358_FUN(clkrst), 20662306a36Sopenharmony_ci BCM6358_FUN(pwm_syn_clk), 20762306a36Sopenharmony_ci BCM6358_FUN(sys_irq), 20862306a36Sopenharmony_ci}; 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_cistatic int bcm6358_pinctrl_get_group_count(struct pinctrl_dev *pctldev) 21162306a36Sopenharmony_ci{ 21262306a36Sopenharmony_ci return ARRAY_SIZE(bcm6358_groups); 21362306a36Sopenharmony_ci} 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_cistatic const char *bcm6358_pinctrl_get_group_name(struct pinctrl_dev *pctldev, 21662306a36Sopenharmony_ci unsigned group) 21762306a36Sopenharmony_ci{ 21862306a36Sopenharmony_ci return bcm6358_groups[group].grp.name; 21962306a36Sopenharmony_ci} 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_cistatic int bcm6358_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, 22262306a36Sopenharmony_ci unsigned group, const unsigned **pins, 22362306a36Sopenharmony_ci unsigned *npins) 22462306a36Sopenharmony_ci{ 22562306a36Sopenharmony_ci *pins = bcm6358_groups[group].grp.pins; 22662306a36Sopenharmony_ci *npins = bcm6358_groups[group].grp.npins; 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci return 0; 22962306a36Sopenharmony_ci} 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_cistatic int bcm6358_pinctrl_get_func_count(struct pinctrl_dev *pctldev) 23262306a36Sopenharmony_ci{ 23362306a36Sopenharmony_ci return ARRAY_SIZE(bcm6358_funcs); 23462306a36Sopenharmony_ci} 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_cistatic const char *bcm6358_pinctrl_get_func_name(struct pinctrl_dev *pctldev, 23762306a36Sopenharmony_ci unsigned selector) 23862306a36Sopenharmony_ci{ 23962306a36Sopenharmony_ci return bcm6358_funcs[selector].name; 24062306a36Sopenharmony_ci} 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_cistatic int bcm6358_pinctrl_get_groups(struct pinctrl_dev *pctldev, 24362306a36Sopenharmony_ci unsigned selector, 24462306a36Sopenharmony_ci const char * const **groups, 24562306a36Sopenharmony_ci unsigned * const num_groups) 24662306a36Sopenharmony_ci{ 24762306a36Sopenharmony_ci *groups = bcm6358_funcs[selector].groups; 24862306a36Sopenharmony_ci *num_groups = bcm6358_funcs[selector].num_groups; 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci return 0; 25162306a36Sopenharmony_ci} 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_cistatic int bcm6358_pinctrl_set_mux(struct pinctrl_dev *pctldev, 25462306a36Sopenharmony_ci unsigned selector, unsigned group) 25562306a36Sopenharmony_ci{ 25662306a36Sopenharmony_ci struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); 25762306a36Sopenharmony_ci struct bcm6358_priv *priv = pc->driver_data; 25862306a36Sopenharmony_ci const struct bcm6358_pingroup *pg = &bcm6358_groups[group]; 25962306a36Sopenharmony_ci unsigned int val = pg->mode_val; 26062306a36Sopenharmony_ci unsigned int mask = val; 26162306a36Sopenharmony_ci unsigned pin; 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci for (pin = 0; pin < pg->grp.npins; pin++) 26462306a36Sopenharmony_ci mask |= (unsigned long)bcm6358_pins[pin].drv_data; 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci regmap_field_update_bits(priv->overlays, mask, val); 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci for (pin = 0; pin < pg->grp.npins; pin++) { 26962306a36Sopenharmony_ci struct pinctrl_gpio_range *range; 27062306a36Sopenharmony_ci unsigned int hw_gpio = bcm6358_pins[pin].number; 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci range = pinctrl_find_gpio_range_from_pin(pctldev, hw_gpio); 27362306a36Sopenharmony_ci if (range) { 27462306a36Sopenharmony_ci struct gpio_chip *gc = range->gc; 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci if (pg->direction & BIT(pin)) 27762306a36Sopenharmony_ci gc->direction_output(gc, hw_gpio, 0); 27862306a36Sopenharmony_ci else 27962306a36Sopenharmony_ci gc->direction_input(gc, hw_gpio); 28062306a36Sopenharmony_ci } 28162306a36Sopenharmony_ci } 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci return 0; 28462306a36Sopenharmony_ci} 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_cistatic int bcm6358_gpio_request_enable(struct pinctrl_dev *pctldev, 28762306a36Sopenharmony_ci struct pinctrl_gpio_range *range, 28862306a36Sopenharmony_ci unsigned offset) 28962306a36Sopenharmony_ci{ 29062306a36Sopenharmony_ci struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); 29162306a36Sopenharmony_ci struct bcm6358_priv *priv = pc->driver_data; 29262306a36Sopenharmony_ci unsigned int mask; 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci mask = (unsigned long) bcm6358_pins[offset].drv_data; 29562306a36Sopenharmony_ci if (!mask) 29662306a36Sopenharmony_ci return 0; 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ci /* disable all functions using this pin */ 29962306a36Sopenharmony_ci return regmap_field_update_bits(priv->overlays, mask, 0); 30062306a36Sopenharmony_ci} 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_cistatic const struct pinctrl_ops bcm6358_pctl_ops = { 30362306a36Sopenharmony_ci .dt_free_map = pinctrl_utils_free_map, 30462306a36Sopenharmony_ci .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, 30562306a36Sopenharmony_ci .get_group_name = bcm6358_pinctrl_get_group_name, 30662306a36Sopenharmony_ci .get_group_pins = bcm6358_pinctrl_get_group_pins, 30762306a36Sopenharmony_ci .get_groups_count = bcm6358_pinctrl_get_group_count, 30862306a36Sopenharmony_ci}; 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_cistatic const struct pinmux_ops bcm6358_pmx_ops = { 31162306a36Sopenharmony_ci .get_function_groups = bcm6358_pinctrl_get_groups, 31262306a36Sopenharmony_ci .get_function_name = bcm6358_pinctrl_get_func_name, 31362306a36Sopenharmony_ci .get_functions_count = bcm6358_pinctrl_get_func_count, 31462306a36Sopenharmony_ci .gpio_request_enable = bcm6358_gpio_request_enable, 31562306a36Sopenharmony_ci .set_mux = bcm6358_pinctrl_set_mux, 31662306a36Sopenharmony_ci .strict = true, 31762306a36Sopenharmony_ci}; 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_cistatic const struct bcm63xx_pinctrl_soc bcm6358_soc = { 32062306a36Sopenharmony_ci .ngpios = BCM6358_NUM_GPIOS, 32162306a36Sopenharmony_ci .npins = ARRAY_SIZE(bcm6358_pins), 32262306a36Sopenharmony_ci .pctl_ops = &bcm6358_pctl_ops, 32362306a36Sopenharmony_ci .pins = bcm6358_pins, 32462306a36Sopenharmony_ci .pmx_ops = &bcm6358_pmx_ops, 32562306a36Sopenharmony_ci}; 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_cistatic int bcm6358_pinctrl_probe(struct platform_device *pdev) 32862306a36Sopenharmony_ci{ 32962306a36Sopenharmony_ci struct reg_field overlays = REG_FIELD(BCM6358_MODE_REG, 0, 15); 33062306a36Sopenharmony_ci struct device *dev = &pdev->dev; 33162306a36Sopenharmony_ci struct bcm63xx_pinctrl *pc; 33262306a36Sopenharmony_ci struct bcm6358_priv *priv; 33362306a36Sopenharmony_ci int err; 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 33662306a36Sopenharmony_ci if (!priv) 33762306a36Sopenharmony_ci return -ENOMEM; 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci err = bcm63xx_pinctrl_probe(pdev, &bcm6358_soc, (void *) priv); 34062306a36Sopenharmony_ci if (err) 34162306a36Sopenharmony_ci return err; 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ci pc = platform_get_drvdata(pdev); 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci priv->overlays = devm_regmap_field_alloc(dev, pc->regs, overlays); 34662306a36Sopenharmony_ci if (IS_ERR(priv->overlays)) 34762306a36Sopenharmony_ci return PTR_ERR(priv->overlays); 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci return 0; 35062306a36Sopenharmony_ci} 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_cistatic const struct of_device_id bcm6358_pinctrl_match[] = { 35362306a36Sopenharmony_ci { .compatible = "brcm,bcm6358-pinctrl", }, 35462306a36Sopenharmony_ci { /* sentinel */ } 35562306a36Sopenharmony_ci}; 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_cistatic struct platform_driver bcm6358_pinctrl_driver = { 35862306a36Sopenharmony_ci .probe = bcm6358_pinctrl_probe, 35962306a36Sopenharmony_ci .driver = { 36062306a36Sopenharmony_ci .name = "bcm6358-pinctrl", 36162306a36Sopenharmony_ci .of_match_table = bcm6358_pinctrl_match, 36262306a36Sopenharmony_ci }, 36362306a36Sopenharmony_ci}; 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_cibuiltin_platform_driver(bcm6358_pinctrl_driver); 366