1/* 2 * Allwinner A31 SoCs special pins pinctrl driver. 3 * 4 * Copyright (C) 2014 Boris Brezillon 5 * Boris Brezillon <boris.brezillon@free-electrons.com> 6 * 7 * Copyright (C) 2014 Maxime Ripard 8 * Maxime Ripard <maxime.ripard@free-electrons.com> 9 * 10 * This file is licensed under the terms of the GNU General Public 11 * License version 2. This program is licensed "as is" without any 12 * warranty of any kind, whether express or implied. 13 */ 14 15#include <linux/module.h> 16#include <linux/platform_device.h> 17#include <linux/of.h> 18#include <linux/of_device.h> 19#include <linux/pinctrl/pinctrl.h> 20#include <linux/reset.h> 21 22#include "pinctrl-sunxi.h" 23 24static const struct sunxi_desc_pin sun6i_a31_r_pins[] = { 25 SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 0), 26 SUNXI_FUNCTION(0x0, "gpio_in"), 27 SUNXI_FUNCTION(0x1, "gpio_out"), 28 SUNXI_FUNCTION(0x2, "s_twi"), /* SCK */ 29 SUNXI_FUNCTION(0x3, "s_p2wi")), /* SCK */ 30 SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 1), 31 SUNXI_FUNCTION(0x0, "gpio_in"), 32 SUNXI_FUNCTION(0x1, "gpio_out"), 33 SUNXI_FUNCTION(0x2, "s_twi"), /* SDA */ 34 SUNXI_FUNCTION(0x3, "s_p2wi")), /* SDA */ 35 SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 2), 36 SUNXI_FUNCTION(0x0, "gpio_in"), 37 SUNXI_FUNCTION(0x1, "gpio_out"), 38 SUNXI_FUNCTION(0x2, "s_uart")), /* TX */ 39 SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 3), 40 SUNXI_FUNCTION(0x0, "gpio_in"), 41 SUNXI_FUNCTION(0x1, "gpio_out"), 42 SUNXI_FUNCTION(0x2, "s_uart")), /* RX */ 43 SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 4), 44 SUNXI_FUNCTION(0x0, "gpio_in"), 45 SUNXI_FUNCTION(0x1, "gpio_out"), 46 SUNXI_FUNCTION(0x2, "s_ir")), /* RX */ 47 SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 5), 48 SUNXI_FUNCTION(0x0, "gpio_in"), 49 SUNXI_FUNCTION(0x1, "gpio_out"), 50 SUNXI_FUNCTION_IRQ_BANK(0x2, 0, 0), /* PL_EINT0 */ 51 SUNXI_FUNCTION(0x3, "s_jtag")), /* MS */ 52 SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 6), 53 SUNXI_FUNCTION(0x0, "gpio_in"), 54 SUNXI_FUNCTION(0x1, "gpio_out"), 55 SUNXI_FUNCTION_IRQ_BANK(0x2, 0, 1), /* PL_EINT1 */ 56 SUNXI_FUNCTION(0x3, "s_jtag")), /* CK */ 57 SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 7), 58 SUNXI_FUNCTION(0x0, "gpio_in"), 59 SUNXI_FUNCTION(0x1, "gpio_out"), 60 SUNXI_FUNCTION_IRQ_BANK(0x2, 0, 2), /* PL_EINT2 */ 61 SUNXI_FUNCTION(0x3, "s_jtag")), /* DO */ 62 SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 8), 63 SUNXI_FUNCTION(0x0, "gpio_in"), 64 SUNXI_FUNCTION(0x1, "gpio_out"), 65 SUNXI_FUNCTION_IRQ_BANK(0x2, 0, 3), /* PL_EINT3 */ 66 SUNXI_FUNCTION(0x3, "s_jtag")), /* DI */ 67 /* Hole */ 68 SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 0), 69 SUNXI_FUNCTION(0x0, "gpio_in"), 70 SUNXI_FUNCTION(0x1, "gpio_out"), 71 SUNXI_FUNCTION_IRQ_BANK(0x2, 1, 0)), /* PM_EINT0 */ 72 SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 1), 73 SUNXI_FUNCTION(0x0, "gpio_in"), 74 SUNXI_FUNCTION(0x1, "gpio_out"), 75 SUNXI_FUNCTION_IRQ_BANK(0x2, 1, 1)), /* PM_EINT1 */ 76 SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 2), 77 SUNXI_FUNCTION(0x0, "gpio_in"), 78 SUNXI_FUNCTION(0x1, "gpio_out"), 79 SUNXI_FUNCTION_IRQ_BANK(0x2, 1, 2), /* PM_EINT2 */ 80 SUNXI_FUNCTION(0x3, "1wire")), 81 SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 3), 82 SUNXI_FUNCTION(0x0, "gpio_in"), 83 SUNXI_FUNCTION(0x1, "gpio_out"), 84 SUNXI_FUNCTION_IRQ_BANK(0x2, 1, 3)), /* PM_EINT3 */ 85 SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 4), 86 SUNXI_FUNCTION(0x0, "gpio_in"), 87 SUNXI_FUNCTION(0x1, "gpio_out"), 88 SUNXI_FUNCTION_IRQ_BANK(0x2, 1, 4)), /* PM_EINT4 */ 89 SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 5), 90 SUNXI_FUNCTION(0x0, "gpio_in"), 91 SUNXI_FUNCTION(0x1, "gpio_out"), 92 SUNXI_FUNCTION_IRQ_BANK(0x2, 1, 5)), /* PM_EINT5 */ 93 SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 6), 94 SUNXI_FUNCTION(0x0, "gpio_in"), 95 SUNXI_FUNCTION(0x1, "gpio_out"), 96 SUNXI_FUNCTION_IRQ_BANK(0x2, 1, 6)), /* PM_EINT6 */ 97 SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 7), 98 SUNXI_FUNCTION(0x0, "gpio_in"), 99 SUNXI_FUNCTION(0x1, "gpio_out"), 100 SUNXI_FUNCTION_IRQ_BANK(0x2, 1, 7), /* PM_EINT7 */ 101 SUNXI_FUNCTION(0x3, "rtc")), /* CLKO */ 102}; 103 104static const struct sunxi_pinctrl_desc sun6i_a31_r_pinctrl_data = { 105 .pins = sun6i_a31_r_pins, 106 .npins = ARRAY_SIZE(sun6i_a31_r_pins), 107 .pin_base = PL_BASE, 108 .irq_banks = 2, 109}; 110 111static int sun6i_a31_r_pinctrl_probe(struct platform_device *pdev) 112{ 113 struct reset_control *rstc; 114 int ret; 115 116 rstc = devm_reset_control_get(&pdev->dev, NULL); 117 if (IS_ERR(rstc)) { 118 dev_err(&pdev->dev, "Reset controller missing\n"); 119 return PTR_ERR(rstc); 120 } 121 122 ret = reset_control_deassert(rstc); 123 if (ret) 124 return ret; 125 126 ret = sunxi_pinctrl_init(pdev, 127 &sun6i_a31_r_pinctrl_data); 128 129 if (ret) 130 reset_control_assert(rstc); 131 132 return ret; 133} 134 135static const struct of_device_id sun6i_a31_r_pinctrl_match[] = { 136 { .compatible = "allwinner,sun6i-a31-r-pinctrl", }, 137 {} 138}; 139MODULE_DEVICE_TABLE(of, sun6i_a31_r_pinctrl_match); 140 141static struct platform_driver sun6i_a31_r_pinctrl_driver = { 142 .probe = sun6i_a31_r_pinctrl_probe, 143 .driver = { 144 .name = "sun6i-a31-r-pinctrl", 145 .of_match_table = sun6i_a31_r_pinctrl_match, 146 }, 147}; 148module_platform_driver(sun6i_a31_r_pinctrl_driver); 149 150MODULE_AUTHOR("Boris Brezillon <boris.brezillon@free-electrons.com"); 151MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com"); 152MODULE_DESCRIPTION("Allwinner A31 R_PIO pinctrl driver"); 153MODULE_LICENSE("GPL"); 154