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(0x3, "s_jtag")), /* MS */ 51 SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 6), 52 SUNXI_FUNCTION(0x0, "gpio_in"), 53 SUNXI_FUNCTION(0x1, "gpio_out"), 54 SUNXI_FUNCTION(0x3, "s_jtag")), /* CK */ 55 SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 7), 56 SUNXI_FUNCTION(0x0, "gpio_in"), 57 SUNXI_FUNCTION(0x1, "gpio_out"), 58 SUNXI_FUNCTION(0x3, "s_jtag")), /* DO */ 59 SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 8), 60 SUNXI_FUNCTION(0x0, "gpio_in"), 61 SUNXI_FUNCTION(0x1, "gpio_out"), 62 SUNXI_FUNCTION(0x3, "s_jtag")), /* DI */ 63 /* Hole */ 64 SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 0), 65 SUNXI_FUNCTION(0x0, "gpio_in"), 66 SUNXI_FUNCTION(0x1, "gpio_out")), 67 SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 1), 68 SUNXI_FUNCTION(0x0, "gpio_in"), 69 SUNXI_FUNCTION(0x1, "gpio_out")), 70 SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 2), 71 SUNXI_FUNCTION(0x0, "gpio_in"), 72 SUNXI_FUNCTION(0x1, "gpio_out"), 73 SUNXI_FUNCTION(0x3, "1wire")), 74 SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 3), 75 SUNXI_FUNCTION(0x0, "gpio_in"), 76 SUNXI_FUNCTION(0x1, "gpio_out")), 77 SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 4), 78 SUNXI_FUNCTION(0x0, "gpio_in"), 79 SUNXI_FUNCTION(0x1, "gpio_out")), 80 SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 5), 81 SUNXI_FUNCTION(0x0, "gpio_in"), 82 SUNXI_FUNCTION(0x1, "gpio_out")), 83 SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 6), 84 SUNXI_FUNCTION(0x0, "gpio_in"), 85 SUNXI_FUNCTION(0x1, "gpio_out")), 86 SUNXI_PIN(SUNXI_PINCTRL_PIN(M, 7), 87 SUNXI_FUNCTION(0x0, "gpio_in"), 88 SUNXI_FUNCTION(0x1, "gpio_out"), 89 SUNXI_FUNCTION(0x3, "rtc")), /* CLKO */ 90}; 91 92static const struct sunxi_pinctrl_desc sun6i_a31_r_pinctrl_data = { 93 .pins = sun6i_a31_r_pins, 94 .npins = ARRAY_SIZE(sun6i_a31_r_pins), 95 .pin_base = PL_BASE, 96 .irq_banks = 2, 97}; 98 99static int sun6i_a31_r_pinctrl_probe(struct platform_device *pdev) 100{ 101 struct reset_control *rstc; 102 int ret; 103 104 rstc = devm_reset_control_get(&pdev->dev, NULL); 105 if (IS_ERR(rstc)) { 106 dev_err(&pdev->dev, "Reset controller missing\n"); 107 return PTR_ERR(rstc); 108 } 109 110 ret = reset_control_deassert(rstc); 111 if (ret) 112 return ret; 113 114 ret = sunxi_pinctrl_init(pdev, 115 &sun6i_a31_r_pinctrl_data); 116 117 if (ret) 118 reset_control_assert(rstc); 119 120 return ret; 121} 122 123static const struct of_device_id sun6i_a31_r_pinctrl_match[] = { 124 { .compatible = "allwinner,sun6i-a31-r-pinctrl", }, 125 {} 126}; 127MODULE_DEVICE_TABLE(of, sun6i_a31_r_pinctrl_match); 128 129static struct platform_driver sun6i_a31_r_pinctrl_driver = { 130 .probe = sun6i_a31_r_pinctrl_probe, 131 .driver = { 132 .name = "sun6i-a31-r-pinctrl", 133 .of_match_table = sun6i_a31_r_pinctrl_match, 134 }, 135}; 136module_platform_driver(sun6i_a31_r_pinctrl_driver); 137 138MODULE_AUTHOR("Boris Brezillon <boris.brezillon@free-electrons.com"); 139MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com"); 140MODULE_DESCRIPTION("Allwinner A31 R_PIO pinctrl driver"); 141MODULE_LICENSE("GPL"); 142