// SPDX-License-Identifier: GPL-2.0 /* * pinctrl driver for Qualcomm ipq9574 * * (C) Copyright 2025 Linaro Ltd. */ #include #include "pinctrl-qcom.h" #define MAX_PIN_NAME_LEN 32 static char pin_name[MAX_PIN_NAME_LEN] __section(".data"); enum ipq9574_functions { msm_mux_blsp0_spi, msm_mux_blsp0_uart, msm_mux_blsp1_i2c, msm_mux_blsp1_spi, msm_mux_blsp1_uart, msm_mux_blsp2_i2c, msm_mux_blsp2_spi, msm_mux_blsp2_uart, msm_mux_blsp3_i2c, msm_mux_blsp3_spi, msm_mux_blsp3_uart, msm_mux_blsp4_i2c, msm_mux_blsp4_spi, msm_mux_blsp4_uart, msm_mux_blsp5_i2c, msm_mux_blsp5_uart, msm_mux_gpio, msm_mux_mdc, msm_mux_mdio, msm_mux_pcie0_clk, msm_mux_pcie0_wake, msm_mux_pcie1_clk, msm_mux_pcie1_wake, msm_mux_pcie2_clk, msm_mux_pcie2_wake, msm_mux_pcie3_clk, msm_mux_pcie3_wake, msm_mux_qspi_data, msm_mux_qspi_clk, msm_mux_qspi_cs, msm_mux_sdc_data, msm_mux_sdc_clk, msm_mux_sdc_cmd, msm_mux_sdc_rclk, msm_mux_NA, }; #define MSM_PIN_FUNCTION(fname) \ [msm_mux_##fname] = {#fname, msm_mux_##fname} static const struct pinctrl_function msm_pinctrl_functions[] = { MSM_PIN_FUNCTION(blsp0_spi), MSM_PIN_FUNCTION(blsp0_uart), MSM_PIN_FUNCTION(blsp1_i2c), MSM_PIN_FUNCTION(blsp1_spi), MSM_PIN_FUNCTION(blsp1_uart), MSM_PIN_FUNCTION(blsp2_i2c), MSM_PIN_FUNCTION(blsp2_spi), MSM_PIN_FUNCTION(blsp2_uart), MSM_PIN_FUNCTION(blsp3_i2c), MSM_PIN_FUNCTION(blsp3_spi), MSM_PIN_FUNCTION(blsp3_uart), MSM_PIN_FUNCTION(blsp4_i2c), MSM_PIN_FUNCTION(blsp4_spi), MSM_PIN_FUNCTION(blsp4_uart), MSM_PIN_FUNCTION(blsp5_i2c), MSM_PIN_FUNCTION(blsp5_uart), MSM_PIN_FUNCTION(gpio), MSM_PIN_FUNCTION(mdc), MSM_PIN_FUNCTION(mdio), MSM_PIN_FUNCTION(pcie0_clk), MSM_PIN_FUNCTION(pcie0_wake), MSM_PIN_FUNCTION(pcie1_clk), MSM_PIN_FUNCTION(pcie1_wake), MSM_PIN_FUNCTION(pcie2_clk), MSM_PIN_FUNCTION(pcie2_wake), MSM_PIN_FUNCTION(pcie3_clk), MSM_PIN_FUNCTION(pcie3_wake), MSM_PIN_FUNCTION(qspi_data), MSM_PIN_FUNCTION(qspi_clk), MSM_PIN_FUNCTION(qspi_cs), MSM_PIN_FUNCTION(sdc_data), MSM_PIN_FUNCTION(sdc_clk), MSM_PIN_FUNCTION(sdc_cmd), MSM_PIN_FUNCTION(sdc_rclk), }; typedef unsigned int msm_pin_function[10]; #define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9) \ [id] = { msm_mux_gpio, /* gpio mode */ \ 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, \ } static const msm_pin_function ipq9574_pin_functions[] = { PINGROUP(0, sdc_data, qspi_data, NA, NA, NA, NA, NA, NA, NA), PINGROUP(1, sdc_data, qspi_data, NA, NA, NA, NA, NA, NA, NA), PINGROUP(2, sdc_data, qspi_data, NA, NA, NA, NA, NA, NA, NA), PINGROUP(3, sdc_data, qspi_data, NA, NA, NA, NA, NA, NA, NA), PINGROUP(4, sdc_cmd, qspi_cs, NA, NA, NA, NA, NA, NA, NA), PINGROUP(5, sdc_clk, qspi_clk, NA, NA, NA, NA, NA, NA, NA), PINGROUP(6, sdc_data, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(7, sdc_data, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(8, sdc_data, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(9, sdc_data, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(10, sdc_rclk, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(11, blsp0_spi, blsp0_uart, NA, NA, NA, NA, NA, NA, NA), PINGROUP(12, blsp0_spi, blsp0_uart, NA, NA, NA, NA, NA, NA, NA), PINGROUP(13, blsp0_spi, blsp0_uart, NA, NA, NA, NA, NA, NA, NA), PINGROUP(14, blsp0_spi, blsp0_uart, NA, NA, NA, NA, NA, NA, NA), PINGROUP(15, blsp3_spi, blsp3_i2c, blsp3_uart, NA, NA, NA, NA, NA, NA), PINGROUP(16, blsp3_spi, blsp3_i2c, blsp3_uart, NA, NA, NA, NA, NA, NA), PINGROUP(17, blsp3_spi, blsp3_uart, NA, NA, NA, NA, NA, NA, NA), PINGROUP(18, blsp3_spi, blsp3_uart, NA, NA, NA, NA, NA, NA, NA), PINGROUP(19, blsp3_spi, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(20, blsp3_spi, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(21, blsp3_spi, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(22, pcie0_clk, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(23, NA, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(24, pcie0_wake, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(25, pcie1_clk, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(26, NA, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(27, pcie1_wake, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(28, pcie2_clk, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(29, NA, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(30, pcie2_wake, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(31, pcie3_clk, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(32, NA, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(33, pcie3_wake, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(34, blsp2_uart, blsp2_i2c, blsp2_spi, blsp1_uart, NA, NA, NA, NA, NA), PINGROUP(35, blsp2_uart, blsp2_i2c, blsp2_spi, blsp1_uart, NA, NA, NA, NA, NA), PINGROUP(36, blsp1_uart, blsp1_i2c, blsp2_spi, NA, NA, NA, NA, NA, NA), PINGROUP(37, blsp1_uart, blsp1_i2c, blsp2_spi, NA, NA, NA, NA, NA, NA), PINGROUP(38, mdc, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(39, mdio, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(40, NA, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(41, NA, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(42, NA, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(43, NA, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(44, NA, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(45, NA, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(46, NA, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(47, NA, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(48, blsp5_i2c, blsp5_uart, NA, NA, NA, NA, NA, NA, NA), PINGROUP(49, blsp5_i2c, blsp5_uart, NA, NA, NA, NA, NA, NA, NA), PINGROUP(50, blsp4_uart, blsp4_i2c, blsp4_spi, NA, NA, NA, NA, NA, NA), PINGROUP(51, blsp4_uart, blsp4_i2c, blsp4_spi, NA, NA, NA, NA, NA, NA), PINGROUP(52, blsp4_uart, blsp4_spi, NA, NA, NA, NA, NA, NA, NA), PINGROUP(53, blsp4_uart, blsp4_spi, NA, NA, NA, NA, NA, NA, NA), PINGROUP(54, NA, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(55, NA, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(56, NA, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(57, NA, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(58, NA, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(59, NA, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(60, NA, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(61, blsp1_spi, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(62, blsp1_spi, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(63, blsp1_spi, NA, NA, NA, NA, NA, NA, NA, NA), PINGROUP(64, blsp1_spi, NA, NA, NA, NA, NA, NA, NA, NA), }; static const char *ipq9574_get_function_name(struct udevice *dev, unsigned int selector) { return msm_pinctrl_functions[selector].name; } static const char *ipq9574_get_pin_name(struct udevice *dev, unsigned int selector) { snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector); return pin_name; } static int ipq9574_get_function_mux(unsigned int pin, unsigned int selector) { unsigned int i; const msm_pin_function *func = ipq9574_pin_functions + pin; for (i = 0; i < 10; i++) if ((*func)[i] == selector) return i; debug("Can't find requested function for pin:selector %u:%u\n", pin, selector); return -EINVAL; } static const struct msm_pinctrl_data ipq9574_data = { .pin_data = { .pin_count = 65, }, .functions_count = ARRAY_SIZE(msm_pinctrl_functions), .get_function_name = ipq9574_get_function_name, .get_function_mux = ipq9574_get_function_mux, .get_pin_name = ipq9574_get_pin_name, }; static const struct udevice_id msm_pinctrl_ids[] = { { .compatible = "qcom,ipq9574-tlmm", .data = (ulong)&ipq9574_data }, { /* Sentinal */ } }; U_BOOT_DRIVER(pinctrl_ipq9574) = { .name = "pinctrl_ipq9574", .id = UCLASS_NOP, .of_match = msm_pinctrl_ids, .ops = &msm_pinctrl_ops, .bind = msm_pinctrl_bind, .flags = DM_FLAG_PRE_RELOC, };