162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Marvell Armada ap806 pinctrl driver based on mvebu pinctrl core 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2017 Marvell 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> 862306a36Sopenharmony_ci * Hanna Hawa <hannah@marvell.com> 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/err.h> 1262306a36Sopenharmony_ci#include <linux/init.h> 1362306a36Sopenharmony_ci#include <linux/io.h> 1462306a36Sopenharmony_ci#include <linux/platform_device.h> 1562306a36Sopenharmony_ci#include <linux/of.h> 1662306a36Sopenharmony_ci#include <linux/of_device.h> 1762306a36Sopenharmony_ci#include <linux/pinctrl/pinctrl.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#include "pinctrl-mvebu.h" 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_cistatic struct mvebu_mpp_mode armada_ap806_mpp_modes[] = { 2262306a36Sopenharmony_ci MPP_MODE(0, 2362306a36Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 2462306a36Sopenharmony_ci MPP_FUNCTION(1, "sdio", "clk"), 2562306a36Sopenharmony_ci MPP_FUNCTION(3, "spi0", "clk")), 2662306a36Sopenharmony_ci MPP_MODE(1, 2762306a36Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 2862306a36Sopenharmony_ci MPP_FUNCTION(1, "sdio", "cmd"), 2962306a36Sopenharmony_ci MPP_FUNCTION(3, "spi0", "miso")), 3062306a36Sopenharmony_ci MPP_MODE(2, 3162306a36Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 3262306a36Sopenharmony_ci MPP_FUNCTION(1, "sdio", "d0"), 3362306a36Sopenharmony_ci MPP_FUNCTION(3, "spi0", "mosi")), 3462306a36Sopenharmony_ci MPP_MODE(3, 3562306a36Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 3662306a36Sopenharmony_ci MPP_FUNCTION(1, "sdio", "d1"), 3762306a36Sopenharmony_ci MPP_FUNCTION(3, "spi0", "cs0n")), 3862306a36Sopenharmony_ci MPP_MODE(4, 3962306a36Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 4062306a36Sopenharmony_ci MPP_FUNCTION(1, "sdio", "d2"), 4162306a36Sopenharmony_ci MPP_FUNCTION(3, "i2c0", "sda")), 4262306a36Sopenharmony_ci MPP_MODE(5, 4362306a36Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 4462306a36Sopenharmony_ci MPP_FUNCTION(1, "sdio", "d3"), 4562306a36Sopenharmony_ci MPP_FUNCTION(3, "i2c0", "sdk")), 4662306a36Sopenharmony_ci MPP_MODE(6, 4762306a36Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 4862306a36Sopenharmony_ci MPP_FUNCTION(1, "sdio", "ds")), 4962306a36Sopenharmony_ci MPP_MODE(7, 5062306a36Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 5162306a36Sopenharmony_ci MPP_FUNCTION(1, "sdio", "d4"), 5262306a36Sopenharmony_ci MPP_FUNCTION(3, "uart1", "rxd")), 5362306a36Sopenharmony_ci MPP_MODE(8, 5462306a36Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 5562306a36Sopenharmony_ci MPP_FUNCTION(1, "sdio", "d5"), 5662306a36Sopenharmony_ci MPP_FUNCTION(3, "uart1", "txd")), 5762306a36Sopenharmony_ci MPP_MODE(9, 5862306a36Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 5962306a36Sopenharmony_ci MPP_FUNCTION(1, "sdio", "d6"), 6062306a36Sopenharmony_ci MPP_FUNCTION(3, "spi0", "cs1n")), 6162306a36Sopenharmony_ci MPP_MODE(10, 6262306a36Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 6362306a36Sopenharmony_ci MPP_FUNCTION(1, "sdio", "d7")), 6462306a36Sopenharmony_ci MPP_MODE(11, 6562306a36Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 6662306a36Sopenharmony_ci MPP_FUNCTION(3, "uart0", "txd")), 6762306a36Sopenharmony_ci MPP_MODE(12, 6862306a36Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 6962306a36Sopenharmony_ci MPP_FUNCTION(1, "sdio", "pw_off"), 7062306a36Sopenharmony_ci MPP_FUNCTION(2, "sdio", "hw_rst")), 7162306a36Sopenharmony_ci MPP_MODE(13, 7262306a36Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL)), 7362306a36Sopenharmony_ci MPP_MODE(14, 7462306a36Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL)), 7562306a36Sopenharmony_ci MPP_MODE(15, 7662306a36Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL)), 7762306a36Sopenharmony_ci MPP_MODE(16, 7862306a36Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL)), 7962306a36Sopenharmony_ci MPP_MODE(17, 8062306a36Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL)), 8162306a36Sopenharmony_ci MPP_MODE(18, 8262306a36Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL)), 8362306a36Sopenharmony_ci MPP_MODE(19, 8462306a36Sopenharmony_ci MPP_FUNCTION(0, "gpio", NULL), 8562306a36Sopenharmony_ci MPP_FUNCTION(3, "uart0", "rxd"), 8662306a36Sopenharmony_ci MPP_FUNCTION(4, "sdio", "pw_off")), 8762306a36Sopenharmony_ci}; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_cistatic struct mvebu_pinctrl_soc_info armada_ap806_pinctrl_info; 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_cistatic const struct of_device_id armada_ap806_pinctrl_of_match[] = { 9262306a36Sopenharmony_ci { 9362306a36Sopenharmony_ci .compatible = "marvell,ap806-pinctrl", 9462306a36Sopenharmony_ci }, 9562306a36Sopenharmony_ci { }, 9662306a36Sopenharmony_ci}; 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_cistatic const struct mvebu_mpp_ctrl armada_ap806_mpp_controls[] = { 9962306a36Sopenharmony_ci MPP_FUNC_CTRL(0, 19, NULL, mvebu_regmap_mpp_ctrl), 10062306a36Sopenharmony_ci}; 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_cistatic struct pinctrl_gpio_range armada_ap806_mpp_gpio_ranges[] = { 10362306a36Sopenharmony_ci MPP_GPIO_RANGE(0, 0, 0, 20), 10462306a36Sopenharmony_ci}; 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_cistatic int armada_ap806_pinctrl_probe(struct platform_device *pdev) 10762306a36Sopenharmony_ci{ 10862306a36Sopenharmony_ci struct mvebu_pinctrl_soc_info *soc = &armada_ap806_pinctrl_info; 10962306a36Sopenharmony_ci const struct of_device_id *match = 11062306a36Sopenharmony_ci of_match_device(armada_ap806_pinctrl_of_match, &pdev->dev); 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci if (!match || !pdev->dev.parent) 11362306a36Sopenharmony_ci return -ENODEV; 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci soc->variant = 0; /* no variants for Armada AP806 */ 11662306a36Sopenharmony_ci soc->controls = armada_ap806_mpp_controls; 11762306a36Sopenharmony_ci soc->ncontrols = ARRAY_SIZE(armada_ap806_mpp_controls); 11862306a36Sopenharmony_ci soc->gpioranges = armada_ap806_mpp_gpio_ranges; 11962306a36Sopenharmony_ci soc->ngpioranges = ARRAY_SIZE(armada_ap806_mpp_gpio_ranges); 12062306a36Sopenharmony_ci soc->modes = armada_ap806_mpp_modes; 12162306a36Sopenharmony_ci soc->nmodes = armada_ap806_mpp_controls[0].npins; 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci pdev->dev.platform_data = soc; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci return mvebu_pinctrl_simple_regmap_probe(pdev, pdev->dev.parent, 0); 12662306a36Sopenharmony_ci} 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_cistatic struct platform_driver armada_ap806_pinctrl_driver = { 12962306a36Sopenharmony_ci .driver = { 13062306a36Sopenharmony_ci .name = "armada-ap806-pinctrl", 13162306a36Sopenharmony_ci .of_match_table = of_match_ptr(armada_ap806_pinctrl_of_match), 13262306a36Sopenharmony_ci }, 13362306a36Sopenharmony_ci .probe = armada_ap806_pinctrl_probe, 13462306a36Sopenharmony_ci}; 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_cibuiltin_platform_driver(armada_ap806_pinctrl_driver); 137