18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Marvell Armada ap806 pinctrl driver based on mvebu pinctrl core 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2017 Marvell 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> 88c2ecf20Sopenharmony_ci * Hanna Hawa <hannah@marvell.com> 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/err.h> 128c2ecf20Sopenharmony_ci#include <linux/init.h> 138c2ecf20Sopenharmony_ci#include <linux/io.h> 148c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 158c2ecf20Sopenharmony_ci#include <linux/of.h> 168c2ecf20Sopenharmony_ci#include <linux/of_device.h> 178c2ecf20Sopenharmony_ci#include <linux/pinctrl/pinctrl.h> 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#include "pinctrl-mvebu.h" 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_cistatic struct mvebu_mpp_mode armada_ap806_mpp_modes[] = { 228c2ecf20Sopenharmony_ci MPP_MODE(0, 238c2ecf20Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 248c2ecf20Sopenharmony_ci MPP_FUNCTION(1, "sdio", "clk"), 258c2ecf20Sopenharmony_ci MPP_FUNCTION(3, "spi0", "clk")), 268c2ecf20Sopenharmony_ci MPP_MODE(1, 278c2ecf20Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 288c2ecf20Sopenharmony_ci MPP_FUNCTION(1, "sdio", "cmd"), 298c2ecf20Sopenharmony_ci MPP_FUNCTION(3, "spi0", "miso")), 308c2ecf20Sopenharmony_ci MPP_MODE(2, 318c2ecf20Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 328c2ecf20Sopenharmony_ci MPP_FUNCTION(1, "sdio", "d0"), 338c2ecf20Sopenharmony_ci MPP_FUNCTION(3, "spi0", "mosi")), 348c2ecf20Sopenharmony_ci MPP_MODE(3, 358c2ecf20Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 368c2ecf20Sopenharmony_ci MPP_FUNCTION(1, "sdio", "d1"), 378c2ecf20Sopenharmony_ci MPP_FUNCTION(3, "spi0", "cs0n")), 388c2ecf20Sopenharmony_ci MPP_MODE(4, 398c2ecf20Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 408c2ecf20Sopenharmony_ci MPP_FUNCTION(1, "sdio", "d2"), 418c2ecf20Sopenharmony_ci MPP_FUNCTION(3, "i2c0", "sda")), 428c2ecf20Sopenharmony_ci MPP_MODE(5, 438c2ecf20Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 448c2ecf20Sopenharmony_ci MPP_FUNCTION(1, "sdio", "d3"), 458c2ecf20Sopenharmony_ci MPP_FUNCTION(3, "i2c0", "sdk")), 468c2ecf20Sopenharmony_ci MPP_MODE(6, 478c2ecf20Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 488c2ecf20Sopenharmony_ci MPP_FUNCTION(1, "sdio", "ds")), 498c2ecf20Sopenharmony_ci MPP_MODE(7, 508c2ecf20Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 518c2ecf20Sopenharmony_ci MPP_FUNCTION(1, "sdio", "d4"), 528c2ecf20Sopenharmony_ci MPP_FUNCTION(3, "uart1", "rxd")), 538c2ecf20Sopenharmony_ci MPP_MODE(8, 548c2ecf20Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 558c2ecf20Sopenharmony_ci MPP_FUNCTION(1, "sdio", "d5"), 568c2ecf20Sopenharmony_ci MPP_FUNCTION(3, "uart1", "txd")), 578c2ecf20Sopenharmony_ci MPP_MODE(9, 588c2ecf20Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 598c2ecf20Sopenharmony_ci MPP_FUNCTION(1, "sdio", "d6"), 608c2ecf20Sopenharmony_ci MPP_FUNCTION(3, "spi0", "cs1n")), 618c2ecf20Sopenharmony_ci MPP_MODE(10, 628c2ecf20Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 638c2ecf20Sopenharmony_ci MPP_FUNCTION(1, "sdio", "d7")), 648c2ecf20Sopenharmony_ci MPP_MODE(11, 658c2ecf20Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 668c2ecf20Sopenharmony_ci MPP_FUNCTION(3, "uart0", "txd")), 678c2ecf20Sopenharmony_ci MPP_MODE(12, 688c2ecf20Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 698c2ecf20Sopenharmony_ci MPP_FUNCTION(1, "sdio", "pw_off"), 708c2ecf20Sopenharmony_ci MPP_FUNCTION(2, "sdio", "hw_rst")), 718c2ecf20Sopenharmony_ci MPP_MODE(13, 728c2ecf20Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL)), 738c2ecf20Sopenharmony_ci MPP_MODE(14, 748c2ecf20Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL)), 758c2ecf20Sopenharmony_ci MPP_MODE(15, 768c2ecf20Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL)), 778c2ecf20Sopenharmony_ci MPP_MODE(16, 788c2ecf20Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL)), 798c2ecf20Sopenharmony_ci MPP_MODE(17, 808c2ecf20Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL)), 818c2ecf20Sopenharmony_ci MPP_MODE(18, 828c2ecf20Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL)), 838c2ecf20Sopenharmony_ci MPP_MODE(19, 848c2ecf20Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 858c2ecf20Sopenharmony_ci MPP_FUNCTION(3, "uart0", "rxd"), 868c2ecf20Sopenharmony_ci MPP_FUNCTION(4, "sdio", "pw_off")), 878c2ecf20Sopenharmony_ci}; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_cistatic struct mvebu_pinctrl_soc_info armada_ap806_pinctrl_info; 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_cistatic const struct of_device_id armada_ap806_pinctrl_of_match[] = { 928c2ecf20Sopenharmony_ci { 938c2ecf20Sopenharmony_ci .compatible = "marvell,ap806-pinctrl", 948c2ecf20Sopenharmony_ci }, 958c2ecf20Sopenharmony_ci { }, 968c2ecf20Sopenharmony_ci}; 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_cistatic const struct mvebu_mpp_ctrl armada_ap806_mpp_controls[] = { 998c2ecf20Sopenharmony_ci MPP_FUNC_CTRL(0, 19, NULL, mvebu_regmap_mpp_ctrl), 1008c2ecf20Sopenharmony_ci}; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_cistatic struct pinctrl_gpio_range armada_ap806_mpp_gpio_ranges[] = { 1038c2ecf20Sopenharmony_ci MPP_GPIO_RANGE(0, 0, 0, 20), 1048c2ecf20Sopenharmony_ci}; 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_cistatic int armada_ap806_pinctrl_probe(struct platform_device *pdev) 1078c2ecf20Sopenharmony_ci{ 1088c2ecf20Sopenharmony_ci struct mvebu_pinctrl_soc_info *soc = &armada_ap806_pinctrl_info; 1098c2ecf20Sopenharmony_ci const struct of_device_id *match = 1108c2ecf20Sopenharmony_ci of_match_device(armada_ap806_pinctrl_of_match, &pdev->dev); 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci if (!match || !pdev->dev.parent) 1138c2ecf20Sopenharmony_ci return -ENODEV; 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci soc->variant = 0; /* no variants for Armada AP806 */ 1168c2ecf20Sopenharmony_ci soc->controls = armada_ap806_mpp_controls; 1178c2ecf20Sopenharmony_ci soc->ncontrols = ARRAY_SIZE(armada_ap806_mpp_controls); 1188c2ecf20Sopenharmony_ci soc->gpioranges = armada_ap806_mpp_gpio_ranges; 1198c2ecf20Sopenharmony_ci soc->ngpioranges = ARRAY_SIZE(armada_ap806_mpp_gpio_ranges); 1208c2ecf20Sopenharmony_ci soc->modes = armada_ap806_mpp_modes; 1218c2ecf20Sopenharmony_ci soc->nmodes = armada_ap806_mpp_controls[0].npins; 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci pdev->dev.platform_data = soc; 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci return mvebu_pinctrl_simple_regmap_probe(pdev, pdev->dev.parent, 0); 1268c2ecf20Sopenharmony_ci} 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_cistatic struct platform_driver armada_ap806_pinctrl_driver = { 1298c2ecf20Sopenharmony_ci .driver = { 1308c2ecf20Sopenharmony_ci .name = "armada-ap806-pinctrl", 1318c2ecf20Sopenharmony_ci .of_match_table = of_match_ptr(armada_ap806_pinctrl_of_match), 1328c2ecf20Sopenharmony_ci }, 1338c2ecf20Sopenharmony_ci .probe = armada_ap806_pinctrl_probe, 1348c2ecf20Sopenharmony_ci}; 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_cibuiltin_platform_driver(armada_ap806_pinctrl_driver); 137