Oleksij Rempel (2):
pinctrl: Add driver for Alphascale asm9260 pinctrl
pinctrl: asm9260: add pinctrl add device tree bindings documentation
.../pinctrl/alphascale,asm9260-pinctrl.txt | 76 +++
drivers/pinctrl/Kconfig | 8 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/pinctrl-asm9260.c | 733 +++++++++++++++++++++
4 files changed, 818 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pinctrl/alphascale,asm9260-pinctrl.txt
create mode 100644 drivers/pinctrl/pinctrl-asm9260.c
--
1.9.1
This patch adds driver for Alphascale asm9260 pinctrl support.
Alphascale asm9260t is SoC based on ARM926EJ (240MHz) in LQFP176 package.
On silicon are:
- 32MB SDRAM
- USB2.0 HS/OTG
- 2x CAN
- SD/MMC
- 5x Times/PWM
- 10x USART
- 24-channel DMA
- 2x i2c
- 2x SPI
- Quad SPI
- 10/100 Ethernet MAC
- Camera IF
- WD
- RTC
- i2s
- GPIO
- 12-bit A/D
- LCD IF
- 8-channel 12-bit ADC
- NAND
Signed-off-by: Oleksij Rempel <[email protected]>
---
drivers/pinctrl/Kconfig | 8 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/pinctrl-asm9260.c | 733 ++++++++++++++++++++++++++++++++++++++
3 files changed, 742 insertions(+)
create mode 100644 drivers/pinctrl/pinctrl-asm9260.c
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index d014f22..054ecbc 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -47,6 +47,14 @@ config PINCTRL_AS3722
open drain configuration for the GPIO pins of AS3722 devices. It also
supports the GPIO functionality through gpiolib.
+config PINCTRL_ASM9260
+ tristate "Pinctrl driver for Alphascale asm9260"
+ depends on MACH_ASM9260
+ select PINMUX
+ select GENERIC_PINCONF
+ help
+ Say Y here to enable the Alphascale asm9260 pinctrl driver
+
config PINCTRL_BF54x
def_bool y if BF54x
select PINCTRL_ADI2
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index c030b3d..46ba7d1c 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -11,6 +11,7 @@ endif
obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o
obj-$(CONFIG_PINCTRL_ADI2) += pinctrl-adi2.o
obj-$(CONFIG_PINCTRL_AS3722) += pinctrl-as3722.o
+obj-$(CONFIG_PINCTRL_ASM9260) += pinctrl-asm9260.o
obj-$(CONFIG_PINCTRL_BF54x) += pinctrl-adi2-bf54x.o
obj-$(CONFIG_PINCTRL_BF60x) += pinctrl-adi2-bf60x.o
obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o
diff --git a/drivers/pinctrl/pinctrl-asm9260.c b/drivers/pinctrl/pinctrl-asm9260.c
new file mode 100644
index 0000000..d31d907
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-asm9260.c
@@ -0,0 +1,733 @@
+/*
+ * Pinctrl driver for the Alphascale ASM9260 SoC
+ *
+ * Copyright (c) 2014, Oleksij Rempel <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+
+#include "core.h"
+#include "pinctrl-utils.h"
+
+/* pinctrl register */
+#define IOCON_PIO0_0 0x0000
+/* only two modes are supported NONE and PULL UP */
+#define IOCON_MODE_SHIFT 3
+#define IOCON_MODE_MASK (0x3 << IOCON_MODE_SHIFT)
+/* Only GPIO0_* pins support pull up. */
+#define IOCON_MODE_PULL_UP (0x2 << IOCON_MODE_SHIFT)
+/* Only GPIO0_* pins don't support pull down. */
+#define IOCON_MODE_PULL_DOWN (0x1 << IOCON_MODE_SHIFT)
+#define IOCON_MODE_NONE (0x0 << IOCON_MODE_SHIFT)
+/* up to 8 functions per pin */
+#define IOCON_PINMUX_MASK (0x7 << 0)
+
+#define MUX_OFFSET(bank, pin) ((bank) * 32 + (pin) * 4)
+
+enum asm9260_mux {
+ ASM9260_MUX_na = -1,
+
+ ASM9260_MUX_gpio0,
+ ASM9260_MUX_cam0,
+ ASM9260_MUX_can0,
+ ASM9260_MUX_can1,
+ ASM9260_MUX_ct0,
+ ASM9260_MUX_ct1,
+ ASM9260_MUX_ct2,
+ ASM9260_MUX_ct3,
+ ASM9260_MUX_i2c0,
+ ASM9260_MUX_i2c1,
+ ASM9260_MUX_i2s0,
+ ASM9260_MUX_i2s1,
+ ASM9260_MUX_jtag,
+ ASM9260_MUX_lcd0,
+ ASM9260_MUX_lcd_if0,
+ ASM9260_MUX_mc,
+ ASM9260_MUX_mc0,
+ ASM9260_MUX_mii0,
+ ASM9260_MUX_nand0,
+ ASM9260_MUX_outclk,
+ ASM9260_MUX_qei0,
+ ASM9260_MUX_qspi0,
+ ASM9260_MUX_rmii0,
+ ASM9260_MUX_sd0,
+ ASM9260_MUX_spi0,
+ ASM9260_MUX_spi1,
+ ASM9260_MUX_uart0,
+ ASM9260_MUX_uart1,
+ ASM9260_MUX_uart2,
+ ASM9260_MUX_uart3,
+ ASM9260_MUX_uart4,
+ ASM9260_MUX_uart5,
+ ASM9260_MUX_uart6,
+ ASM9260_MUX_uart7,
+ ASM9260_MUX_uart8,
+ ASM9260_MUX_uart9,
+};
+
+struct asm9260_function {
+ const char *name;
+ const char **groups;
+ unsigned int ngroups;
+};
+
+#define FUNCTION(mux) \
+ [(ASM9260_MUX_ ## mux)] = { \
+ .name = #mux, \
+ .groups = NULL, \
+ .ngroups = 0, \
+ }
+
+static struct asm9260_function asm9260_functions[] = {
+ FUNCTION(gpio0),
+ FUNCTION(cam0),
+ FUNCTION(can0),
+ FUNCTION(can1),
+ FUNCTION(ct0),
+ FUNCTION(ct1),
+ FUNCTION(ct2),
+ FUNCTION(ct3),
+ FUNCTION(i2c0),
+ FUNCTION(i2c1),
+ FUNCTION(i2s0),
+ FUNCTION(i2s1),
+ FUNCTION(jtag),
+ FUNCTION(lcd0),
+ FUNCTION(lcd_if0),
+ FUNCTION(mc),
+ FUNCTION(mc0),
+ FUNCTION(mii0),
+ FUNCTION(nand0),
+ FUNCTION(outclk),
+ FUNCTION(qei0),
+ FUNCTION(qspi0),
+ FUNCTION(rmii0),
+ FUNCTION(sd0),
+ FUNCTION(spi0),
+ FUNCTION(spi1),
+ FUNCTION(uart0),
+ FUNCTION(uart1),
+ FUNCTION(uart2),
+ FUNCTION(uart3),
+ FUNCTION(uart4),
+ FUNCTION(uart5),
+ FUNCTION(uart6),
+ FUNCTION(uart7),
+ FUNCTION(uart8),
+ FUNCTION(uart9),
+};
+
+struct asm9260_pingroup {
+ const char *name;
+ const unsigned int number;
+ const unsigned int bank;
+ const unsigned int pin;
+
+#define MAX_FUNCS_PER_PIN 8
+ const int funcs[MAX_FUNCS_PER_PIN];
+};
+
+#define PMUX(p_number, p_bank, p_pin, p_name, f1, f2, f3, f4, f5, f6, f7) \
+ { \
+ .number = p_number, \
+ .bank = p_bank, \
+ .pin = p_pin, \
+ .name = #p_name, \
+ .funcs = { \
+ ASM9260_MUX_gpio0, \
+ ASM9260_MUX_ ## f1, \
+ ASM9260_MUX_ ## f2, \
+ ASM9260_MUX_ ## f3, \
+ ASM9260_MUX_ ## f4, \
+ ASM9260_MUX_ ## f5, \
+ ASM9260_MUX_ ## f6, \
+ ASM9260_MUX_ ## f7, \
+ }, \
+ }
+
+static struct asm9260_pingroup asm9260_mux_table[] = {
+ PMUX(120, 0, 0, GPIO0_0,
+ na, uart1, i2s0, spi1, na, jtag, na),
+ PMUX(121, 0, 1, GPIO0_1,
+ na, uart1, i2s0, spi1, na, jtag, na),
+ PMUX(122, 0, 2, GPIO0_2,
+ na, uart1, i2s0, spi1, na, jtag, na),
+ PMUX(123, 0, 3, GPIO0_3,
+ na, uart1, i2s0, spi1, na, jtag, na),
+ PMUX(124, 0, 4, GPIO0_4,
+ na, uart1, i2s0, spi0, na, jtag, i2c0),
+ PMUX(128, 1, 4, GPIO1_4,
+ ct0, uart0, lcd_if0, spi0, mii0, lcd0, na),
+ PMUX(129, 1, 5, GPIO1_5,
+ na, uart0, lcd_if0, spi0, rmii0, lcd0, na),
+ PMUX(130, 1, 6, GPIO1_6,
+ na, uart0, lcd_if0, spi0, rmii0, lcd0, i2c1),
+ PMUX(131, 1, 7, GPIO1_7,
+ na, uart0, lcd_if0, spi0, rmii0, lcd0, i2c1),
+ PMUX(132, 2, 0, GPIO2_0,
+ ct1, uart2, lcd_if0, spi1, mii0, lcd0, can0),
+ PMUX(133, 2, 1, GPIO2_1,
+ ct1, uart2, lcd_if0, spi1, mii0, lcd0, can0),
+ PMUX(134, 2, 2, GPIO2_2,
+ ct1, uart3, lcd_if0, spi1, mii0, lcd0, na),
+ PMUX(135, 2, 3, GPIO2_3,
+ ct1, uart3, lcd_if0, spi1, mii0, lcd0, na),
+ PMUX(136, 2, 4, GPIO2_4,
+ ct1, uart3, lcd_if0, na, mii0, lcd0, na),
+ PMUX(137, 2, 5, GPIO2_5,
+ na, uart3, lcd_if0, na, mii0, lcd0, outclk),
+ PMUX(138, 2, 6, GPIO2_6,
+ na, uart3, lcd_if0, na, mii0, lcd0, can1),
+ PMUX(139, 2, 7, GPIO2_7,
+ na, uart4, lcd_if0, na, mii0, lcd0, can1),
+ PMUX(140, 3, 0, GPIO3_0,
+ ct2, uart4, lcd_if0, sd0, rmii0, lcd0, na),
+ PMUX(141, 3, 1, GPIO3_1,
+ ct2, uart4, lcd_if0, sd0, rmii0, lcd0, na),
+ PMUX(142, 3, 2, GPIO3_2,
+ ct2, uart4, lcd_if0, sd0, rmii0, lcd0, can1),
+ PMUX(143, 3, 3, GPIO3_3,
+ ct2, uart4, lcd_if0, sd0, rmii0, lcd0, can1),
+ PMUX(144, 3, 4, GPIO3_4,
+ ct2, uart5, lcd_if0, sd0, rmii0, lcd0, outclk),
+ PMUX(145, 3, 5, GPIO3_5,
+ na, uart5, lcd_if0, sd0, rmii0, lcd0, i2c0),
+ PMUX(146, 3, 6, GPIO3_6,
+ na, uart5, lcd_if0, na, rmii0, lcd0, i2c0),
+ PMUX(147, 3, 7, GPIO3_7,
+ na, uart5, lcd_if0, na, rmii0, lcd0, na),
+ PMUX(151, 4, 0, GPIO4_0,
+ ct3, uart5, na, qspi0, mii0, lcd0, na),
+ PMUX(152, 4, 1, GPIO4_1,
+ ct3, uart6, na, qspi0, mii0, lcd0, na),
+ PMUX(153, 4, 2, GPIO4_2,
+ ct3, uart6, na, qspi0, mii0, lcd0, na),
+ PMUX(154, 4, 3, GPIO4_3,
+ ct3, uart6, na, qspi0, mii0, lcd0, na),
+ PMUX(155, 4, 4, GPIO4_4,
+ ct3, uart6, na, qspi0, mii0, lcd0, na),
+ PMUX(156, 4, 5, GPIO4_5,
+ na, uart6, na, qspi0, mii0, lcd0, na),
+ PMUX(157, 4, 6, GPIO4_6,
+ na, na, na, na, mii0, lcd0, i2c1),
+ PMUX(158, 4, 7, GPIO4_7,
+ na, na, na, na, mii0, lcd0, i2c1),
+ PMUX(169, 5, 0, GPIO5_0,
+ mc0, uart7, i2s1, sd0, rmii0, na, na),
+ PMUX(170, 5, 1, GPIO5_1,
+ mc0, uart7, i2s1, sd0, rmii0, na, na),
+ PMUX(171, 5, 2, GPIO5_2,
+ mc0, uart7, i2s1, sd0, rmii0, na, can0),
+ PMUX(172, 5, 3, GPIO5_3,
+ mc0, uart7, i2s1, sd0, rmii0, na, can0),
+ PMUX(173, 5, 4, GPIO5_4,
+ mc0, uart8, i2s1, sd0, rmii0, na, na),
+ PMUX(51, 8, 1, GPIO8_1,
+ na, uart2, cam0, na, mii0, na, na),
+ PMUX(52, 8, 2, GPIO8_2,
+ na, uart2, cam0, na, mii0, na, na),
+ PMUX(53, 8, 3, GPIO8_3,
+ na, uart2, cam0, na, mii0, na, na),
+ PMUX(54, 8, 4, GPIO8_4,
+ na, uart2, cam0, na, mii0, na, na),
+ PMUX(55, 8, 5, GPIO8_5,
+ na, uart3, cam0, na, mii0, na, na),
+ PMUX(56, 8, 6, GPIO8_6,
+ na, uart3, cam0, na, mii0, na, na),
+ PMUX(57, 8, 7, GPIO8_7,
+ na, uart3, cam0, na, mii0, na, na),
+ PMUX(45, 9, 0, GPIO9_0,
+ ct0, uart3, cam0, na, rmii0, na, i2c0),
+ PMUX(46, 9, 1, GPIO9_1,
+ ct0, uart3, cam0, na, rmii0, na, i2c0),
+ PMUX(47, 9, 2, GPIO9_2,
+ ct0, uart4, cam0, na, rmii0, na, na),
+ PMUX(48, 9, 3, GPIO9_3,
+ ct0, uart4, cam0, na, rmii0, na, na),
+ PMUX(49, 9, 4, GPIO9_4,
+ ct0, uart4, cam0, na, rmii0, na, na),
+ PMUX(50, 9, 5, GPIO9_5,
+ na, uart4, cam0, na, rmii0, na, i2c1),
+ PMUX(4, 10, 0, GPIO10_0,
+ ct1, uart5, i2s0, spi0, na, na, na),
+ PMUX(5, 10, 1, GPIO10_1,
+ ct1, uart5, i2s0, spi0, rmii0, na, na),
+ PMUX(6, 10, 2, GPIO10_2,
+ ct1, uart5, i2s0, spi0, rmii0, na, na),
+ PMUX(7, 10, 3, GPIO10_3,
+ ct1, uart5, i2s0, spi0, na, na, can0),
+ PMUX(8, 10, 4, GPIO10_4,
+ ct1, uart6, i2s0, spi1, rmii0, na, na),
+ PMUX(9, 10, 5, GPIO10_5,
+ na, uart6, i2s0, spi1, rmii0, na, can1),
+ PMUX(10, 10, 6, GPIO10_6,
+ na, uart6, i2s0, spi1, rmii0, na, can1),
+ PMUX(11, 10, 7, GPIO10_7,
+ na, uart6, cam0, spi1, rmii0, na, na),
+ PMUX(12, 11, 0, GPIO11_0,
+ ct2, uart7, i2s1, qspi0, nand0, na, na),
+ PMUX(13, 11, 1, GPIO11_1,
+ ct2, uart7, i2s1, qspi0, nand0, na, na),
+ PMUX(14, 11, 2, GPIO11_2,
+ ct2, uart7, i2s1, qspi0, nand0, na, na),
+ PMUX(15, 11, 3, GPIO11_3,
+ ct2, uart7, i2s1, qspi0, nand0, na, na),
+ PMUX(16, 11, 4, GPIO11_4,
+ ct2, uart8, i2s1, qspi0, nand0, na, na),
+ PMUX(17, 11, 5, GPIO11_5,
+ na, uart8, i2s1, qspi0, nand0, na, na),
+ PMUX(18, 11, 6, GPIO11_6,
+ na, uart9, i2s1, na, nand0, na, i2c0),
+ PMUX(19, 11, 7, GPIO11_7,
+ na, uart9, cam0, na, nand0, na, i2c0),
+ PMUX(23, 12, 0, GPIO12_0,
+ ct3, uart1, na, sd0, nand0, na, na),
+ PMUX(24, 12, 1, GPIO12_1,
+ ct3, uart1, na, sd0, nand0, na, na),
+ PMUX(25, 12, 2, GPIO12_2,
+ ct3, uart1, na, sd0, nand0, na, na),
+ PMUX(26, 12, 3, GPIO12_3,
+ ct3, uart1, na, sd0, nand0, na, na),
+ PMUX(27, 12, 4, GPIO12_4,
+ ct3, uart1, na, sd0, nand0, na, na),
+ PMUX(28, 12, 5, GPIO12_5,
+ na, uart8, na, sd0, nand0, na, na),
+ PMUX(29, 12, 6, GPIO12_6,
+ na, uart8, cam0, na, nand0, na, i2c1),
+ PMUX(30, 12, 7, GPIO12_7,
+ na, na, cam0, na, nand0, na, i2c1),
+ PMUX(31, 13, 4, GPIO13_4,
+ mc, uart2, na, spi1, nand0, na, na),
+ PMUX(32, 13, 5, GPIO13_5,
+ mc0, uart9, na, spi1, nand0, na, na),
+ PMUX(33, 13, 6, GPIO13_6,
+ mc0, uart9, na, spi1, nand0, na, na),
+ PMUX(34, 13, 7, GPIO13_7,
+ mc0, na, na, spi1, nand0, na, na),
+ PMUX(38, 14, 0, GPIO14_0,
+ mc0, uart0, i2s0, sd0, nand0, na, na),
+ PMUX(39, 14, 1, GPIO14_1,
+ mc0, uart0, i2s0, sd0, nand0, na, na),
+ PMUX(40, 14, 2, GPIO14_2,
+ na, uart0, i2s0, sd0, nand0, na, na),
+ PMUX(41, 14, 3, GPIO14_3,
+ na, uart0, i2s0, sd0, nand0, na, na),
+ PMUX(42, 14, 4, GPIO14_4,
+ na, uart0, i2s0, sd0, nand0, na, na),
+ PMUX(43, 14, 5, GPIO14_5,
+ na, uart0, i2s0, sd0, nand0, na, na),
+ PMUX(44, 15, 0, GPIO15_0,
+ na, uart4, i2s0, sd0, rmii0, na, na),
+ PMUX(61, 15, 1, GPIO15_1,
+ na, uart4, i2s0, sd0, rmii0, na, na),
+ PMUX(62, 15, 2, GPIO15_2,
+ na, uart5, i2s0, sd0, rmii0, na, na),
+ PMUX(63, 15, 3, GPIO15_3,
+ na, uart5, i2s0, sd0, rmii0, na, na),
+ PMUX(64, 15, 4, GPIO15_4,
+ na, uart6, i2s0, sd0, rmii0, na, na),
+ PMUX(65, 15, 5, GPIO15_5,
+ na, uart6, i2s0, sd0, rmii0, na, na),
+ PMUX(66, 15, 6, GPIO15_6,
+ na, uart7, i2s0, na, rmii0, na, na),
+ PMUX(67, 15, 7, GPIO15_7,
+ na, uart7, na, na, rmii0, na, na),
+ PMUX(73, 16, 0, GPIO16_0,
+ ct2, uart4, na, na, mii0, na, na),
+ PMUX(74, 16, 1, GPIO16_1,
+ ct2, uart4, na, na, mii0, na, na),
+ PMUX(75, 16, 2, GPIO16_2,
+ ct2, uart5, na, na, mii0, na, na),
+ PMUX(76, 16, 3, GPIO16_3,
+ ct2, uart5, na, na, mii0, na, na),
+ PMUX(77, 16, 4, GPIO16_4,
+ ct2, uart6, na, na, mii0, na, na),
+ PMUX(78, 16, 5, GPIO16_5,
+ qei0, uart6, na, na, mii0, na, na),
+ PMUX(79, 16, 6, GPIO16_6,
+ qei0, uart6, na, na, mii0, na, can1),
+ PMUX(80, 16, 7, GPIO16_7,
+ qei0, uart6, na, na, mii0, na, can1),
+ PMUX(81, 17, 0, GPIO17_0,
+ ct3, uart7, i2s1, na, rmii0, na, na),
+ PMUX(82, 17, 1, GPIO17_1,
+ ct3, uart7, i2s1, na, na, na, na),
+ PMUX(83, 17, 2, GPIO17_2,
+ ct3, uart7, i2s1, na, na, na, i2c1),
+ PMUX(84, 17, 3, GPIO17_3,
+ ct3, uart7, i2s1, na, na, na, i2c1),
+ PMUX(85, 17, 4, GPIO17_4,
+ ct3, uart8, i2s1, na, na, na, na),
+ PMUX(86, 17, 5, GPIO17_5,
+ qei0, uart8, i2s1, na, rmii0, na, na),
+ PMUX(87, 17, 6, GPIO17_6,
+ qei0, uart9, i2s1, na, mii0, na, na),
+ PMUX(88, 17, 7, GPIO17_7,
+ qei0, uart9, na, na, mii0, na, na),
+};
+
+#define MUX_TABLE_SIZE ARRAY_SIZE(asm9260_mux_table)
+struct asm9260_pmx_priv {
+ struct device *dev;
+ struct pinctrl_dev *pctl;
+ void __iomem *iobase;
+
+ struct clk *clk;
+ spinlock_t lock;
+
+ struct pinctrl_pin_desc pin_desc[MUX_TABLE_SIZE];
+};
+
+static void __init asm9260_init_mux_pins(struct asm9260_pmx_priv *priv)
+{
+ unsigned int i;
+
+ for (i = 0; i < MUX_TABLE_SIZE; i++) {
+ priv->pin_desc[i].name = asm9260_mux_table[i].name;
+ priv->pin_desc[i].number = asm9260_mux_table[i].number;
+ }
+}
+
+/*
+ * Pin control operations
+ */
+
+/* each GPIO pin has it's own pseudo pingroup containing only itself */
+static int asm9260_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+ return MUX_TABLE_SIZE;
+}
+
+static const char *asm9260_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
+ unsigned int group)
+{
+ struct asm9260_pmx_priv *priv = pinctrl_dev_get_drvdata(pctldev);
+
+ return priv->pin_desc[group].name;
+}
+
+static int asm9260_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+ unsigned int group,
+ const unsigned int **pins,
+ unsigned int *num_pins)
+{
+ struct asm9260_pmx_priv *priv = pinctrl_dev_get_drvdata(pctldev);
+
+ *pins = &priv->pin_desc[group].number;
+ *num_pins = 1;
+
+ return 0;
+}
+
+static struct pinctrl_ops asm9260_pinctrl_ops = {
+ .get_groups_count = asm9260_pinctrl_get_groups_count,
+ .get_group_name = asm9260_pinctrl_get_group_name,
+ .get_group_pins = asm9260_pinctrl_get_group_pins,
+ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
+ .dt_free_map = pinctrl_utils_dt_free_map,
+};
+
+/*
+ * Pin mux operations
+ */
+static int asm9260_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
+{
+ return ARRAY_SIZE(asm9260_functions);
+}
+
+static const char *asm9260_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
+ unsigned int function)
+{
+ return asm9260_functions[function].name;
+}
+
+static int asm9260_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
+ unsigned int function,
+ const char * const **groups,
+ unsigned int * const num_groups)
+{
+ struct asm9260_pmx_priv *priv = pinctrl_dev_get_drvdata(pctldev);
+ struct asm9260_pingroup *table;
+ int a, b, count = 0, *tmp;
+ const char **gr;
+
+ if (asm9260_functions[function].groups != NULL)
+ goto done;
+
+ tmp = devm_kmalloc(priv->dev, sizeof(tmp) * MUX_TABLE_SIZE, GFP_KERNEL);
+ if (!tmp) {
+ dev_err(priv->dev, "Can't allocate func/pin array\n");
+ return PTR_ERR(tmp);
+ }
+
+ for (a = 0; a < MUX_TABLE_SIZE; a++) {
+ table = &asm9260_mux_table[a];
+
+ for (b = 0; b < MAX_FUNCS_PER_PIN; b++) {
+ if (table->funcs[b] == function) {
+ tmp[count] = a;
+ count++;
+ }
+
+ }
+
+ }
+
+ gr = devm_kmalloc(priv->dev,
+ sizeof(gr) * count, GFP_KERNEL);
+ if (!gr) {
+ dev_err(priv->dev, "Can't allocate func group\n");
+ devm_kfree(priv->dev, tmp);
+ return PTR_ERR(gr);
+ }
+
+ for (a = 0; a < count; a++)
+ gr[a] = asm9260_mux_table[tmp[a]].name;
+
+ asm9260_functions[function].groups = gr;
+ asm9260_functions[function].ngroups = count;
+done:
+ *groups = asm9260_functions[function].groups;
+ *num_groups = asm9260_functions[function].ngroups;
+ return 0;
+}
+
+static int asm9260_pinctrl_set_mux(struct pinctrl_dev *pctldev,
+ unsigned int function, unsigned int pin)
+{
+ struct asm9260_pmx_priv *priv = pinctrl_dev_get_drvdata(pctldev);
+ struct asm9260_pingroup *table;
+ void __iomem *offset;
+ int mux;
+ u32 val;
+
+ table = &asm9260_mux_table[pin];
+ for (mux = 0; mux < MAX_FUNCS_PER_PIN; ++mux) {
+ if (table->funcs[mux] == function)
+ goto found_mux;
+ }
+
+ return -EINVAL;
+
+found_mux:
+ offset = priv->iobase + MUX_OFFSET(table->bank, table->pin);
+ spin_lock(&priv->lock);
+ val = ioread32(offset);
+ val &= ~IOCON_PINMUX_MASK;
+ val |= mux;
+ iowrite32(val, offset);
+ spin_unlock(&priv->lock);
+
+ return 0;
+}
+
+static struct pinmux_ops asm9260_pinmux_ops = {
+ .get_functions_count = asm9260_pinctrl_get_funcs_count,
+ .get_function_name = asm9260_pinctrl_get_func_name,
+ .get_function_groups = asm9260_pinctrl_get_func_groups,
+ .set_mux = asm9260_pinctrl_set_mux,
+ /* TODO: should we care about gpios here? gpio_request_enable? */
+};
+
+static int asm9260_pinconf_reg(struct pinctrl_dev *pctldev,
+ unsigned int pin,
+ enum pin_config_param param,
+ void __iomem **reg, u32 *val)
+{
+ struct asm9260_pmx_priv *priv = pinctrl_dev_get_drvdata(pctldev);
+ struct asm9260_pingroup *table;
+ int a;
+
+ for (a = 0; a < MUX_TABLE_SIZE; a++) {
+ table = &asm9260_mux_table[a];
+ if (table->number == pin)
+ break;
+ }
+
+ *reg = priv->iobase + MUX_OFFSET(table->bank, table->pin);
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ *val = IOCON_MODE_NONE;
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ if (table->bank != 0)
+ return -ENOTSUPP;
+ *val = IOCON_MODE_PULL_UP;
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ if (table->bank == 0)
+ return -ENOTSUPP;
+ *val = IOCON_MODE_PULL_DOWN;
+ break;
+ default:
+ return -ENOTSUPP;
+ };
+
+ return 0;
+}
+
+static int asm9260_pinconf_get(struct pinctrl_dev *pctldev,
+ unsigned int pin, unsigned long *config)
+{
+ enum pin_config_param param = pinconf_to_config_param(*config);
+ void __iomem *reg;
+ u32 val, tmp, arg;
+ int ret;
+
+ /* Get register information */
+ ret = asm9260_pinconf_reg(pctldev, pin, param,
+ ®, &val);
+ if (ret < 0)
+ return ret;
+
+ /* Extract field from register */
+ tmp = ioread32(reg);
+ arg = (tmp & IOCON_MODE_MASK) == val;
+ if (!arg)
+ return -EINVAL;
+
+ /* And pack config */
+ *config = pinconf_to_config_packed(param, arg);
+
+ return 0;
+}
+
+static int asm9260_pinconf_set(struct pinctrl_dev *pctldev,
+ unsigned int pin, unsigned long *configs,
+ unsigned num_configs)
+{
+ struct asm9260_pmx_priv *priv = pinctrl_dev_get_drvdata(pctldev);
+ enum pin_config_param param;
+ unsigned int arg;
+ int ret;
+ u32 val, tmp;
+ void __iomem *reg;
+ int i;
+
+ for (i = 0; i < num_configs; i++) {
+ param = pinconf_to_config_param(configs[i]);
+ arg = pinconf_to_config_argument(configs[i]);
+
+ /* Get register information */
+ ret = asm9260_pinconf_reg(pctldev, pin, param,
+ ®, &val);
+ if (ret < 0)
+ return ret;
+
+ spin_lock(&priv->lock);
+ tmp = ioread32(reg);
+ tmp &= ~IOCON_MODE_MASK;
+ if (arg)
+ tmp |= val;
+ iowrite32(tmp, reg);
+ spin_unlock(&priv->lock);
+ }
+
+ return 0;
+}
+
+static struct pinconf_ops asm9260_pinconf_ops = {
+ .is_generic = true,
+ .pin_config_get = asm9260_pinconf_get,
+ .pin_config_set = asm9260_pinconf_set,
+};
+
+/*
+ * Pin control driver setup
+ */
+static struct pinctrl_desc asm9260_pinctrl_desc = {
+ .pctlops = &asm9260_pinctrl_ops,
+ .pmxops = &asm9260_pinmux_ops,
+ .confops = &asm9260_pinconf_ops,
+ .owner = THIS_MODULE,
+};
+
+static int asm9260_pinctrl_probe(struct platform_device *pdev)
+{
+ struct asm9260_pmx_priv *priv;
+ struct resource *res;
+ int ret;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv) {
+ dev_err(&pdev->dev, "Can't alloc asm9260_priv\n");
+ return -ENOMEM;
+ }
+ priv->dev = &pdev->dev;
+ spin_lock_init(&priv->lock);
+
+ asm9260_init_mux_pins(priv);
+
+ asm9260_pinctrl_desc.name = dev_name(&pdev->dev);
+ asm9260_pinctrl_desc.pins = priv->pin_desc;
+ asm9260_pinctrl_desc.npins = MUX_TABLE_SIZE;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ priv->iobase = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(priv->iobase))
+ return PTR_ERR(priv->iobase);
+
+ priv->clk = devm_clk_get(&pdev->dev, "ahb");
+ ret = clk_prepare_enable(priv->clk);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to enable clk!\n");
+ return ret;
+ }
+
+ priv->pctl = pinctrl_register(&asm9260_pinctrl_desc, &pdev->dev, priv);
+ if (!priv->pctl) {
+ dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
+ ret = -ENODEV;
+ goto err_return;
+ }
+
+ platform_set_drvdata(pdev, priv);
+
+ dev_info(&pdev->dev, "ASM9260 pinctrl driver initialised\n");
+
+ return 0;
+err_return:
+ clk_disable_unprepare(priv->clk);
+ return ret;
+}
+
+static int asm9260_pinctrl_remove(struct platform_device *pdev)
+{
+ struct asm9260_pmx_priv *priv = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(priv->clk);
+ pinctrl_unregister(priv->pctl);
+
+ return 0;
+}
+
+static struct of_device_id asm9260_pinctrl_of_match[] = {
+ { .compatible = "alphascale,asm9260-pinctrl", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, asm9260_pinctrl_of_match);
+
+static struct platform_driver asm9260_pinctrl_driver = {
+ .driver = {
+ .name = "asm9260-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = asm9260_pinctrl_of_match,
+ },
+ .probe = asm9260_pinctrl_probe,
+ .remove = asm9260_pinctrl_remove,
+};
+module_platform_driver(asm9260_pinctrl_driver);
+
+MODULE_AUTHOR("Oleksij Rempel <[email protected]>");
+MODULE_DESCRIPTION("Alphascale ASM9260 pinctrl driver");
+MODULE_LICENSE("GPL");
--
1.9.1
Add device tree bindings documentation for Alphascale asm9260 pin controller
Signed-off-by: Oleksij Rempel <[email protected]>
---
.../pinctrl/alphascale,asm9260-pinctrl.txt | 76 ++++++++++++++++++++++
1 file changed, 76 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pinctrl/alphascale,asm9260-pinctrl.txt
diff --git a/Documentation/devicetree/bindings/pinctrl/alphascale,asm9260-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/alphascale,asm9260-pinctrl.txt
new file mode 100644
index 0000000..dbeea4d
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/alphascale,asm9260-pinctrl.txt
@@ -0,0 +1,76 @@
+* Alphascale ASM9260 SoC pinctrl core driver
+
+The pinctrl driver enables Alphascale ASM9260 to configure pin multiplexing
+to a specific function.
+
+Required properties for pinctrl driver:
+- compatible: "alphascale,asm9260-pinctrl"
+- reg: Register base of the MPP block and length.
+- clocks: clock ids.
+- clock-names:
+ * 1 "ahb" : AHB gating clock.
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices, including the meaning of the
+phrase "pin configuration node".
+
+The pin configuration nodes act as a container for an arbitrary number of
+subnodes. Each of these subnodes represents some desired configuration for a
+pin or a list of pins. This configuration can include the
+mux function to select on those pin(s), and various pin configuration
+parameters, as listed below.
+
+SUBNODES:
+
+The name of each subnode is not important; all subnodes should be enumerated
+and processed purely based on their content.
+
+Each subnode only affects those parameters that are explicitly listed. In
+other words, a subnode that lists a mux function but no pin configuration
+parameters implies no information about any pin configuration parameters.
+Similarly, a pin subnode that describes a pullup parameter implies no
+information about e.g. the mux function.
+
+The following generic properties as defined in pinctrl-bindings.txt are valid
+to specify in a pin configuration subnode:
+pins - the list of pins that properties in the node
+ apply to (either this or "groups" has to be
+ specified)
+function - the mux function to select
+bias-disable - disable any pin bias
+bias-pull-up - pull up the pin. Supported only on GPIO0_* pins.
+bias-pull-down - pull down the pin. Supported on all pins except of GPIO0_*.
+
+Examples:
+
+pinctrl: pinctrl@80044000 {
+ compatible = "alphascale,asm9260-pinctrl";
+ reg = <0x80044000 0x400>;
+ clocks = <&acc CLKID_AHB_IOCONFIG>;
+ clock-names = "ahb";
+
+ nand_fc0_pins_a: nand_fc0 {
+ nand_main_gr {
+ pins = "GPIO11_0", "GPIO11_1", "GPIO11_2",
+ "GPIO11_3", "GPIO11_4", "GPIO11_6",
+ "GPIO12_0", "GPIO12_1", "GPIO12_2",
+ "GPIO12_3", "GPIO12_4", "GPIO12_5",
+ "GPIO12_6", "GPIO12_7";
+ function = "nand0";
+ bias-disable;
+ };
+ };
+};
+
+nand_controller0 {
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ nand-ecc-strength = <4>;
+ nand-ecc-step-size = <512>;
+ nand-max-chips = <1>;
+ nand-on-flash-bbt;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&nand_fc0_pins_a>;
+};
--
1.9.1
A license nit follows.
On Sun, 2015-04-05 at 08:26 +0200, Oleksij Rempel wrote:
> --- /dev/null
> +++ b/drivers/pinctrl/pinctrl-asm9260.c
> @@ -0,0 +1,733 @@
> +/*
> + * Pinctrl driver for the Alphascale ASM9260 SoC
> + *
> + * Copyright (c) 2014, Oleksij Rempel <[email protected]>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + */
This states the license of this file is GPL v2.
> +MODULE_LICENSE("GPL");
Your reading of include/linux/module.h (see
https://lkml.org/lkml/2015/4/5/7 ) is incorrect. Because according to
that header "GPL" means
GNU Public License v2 or later
while "GPL v2" means
GNU Public License v2
So only "GPL v2" matches what's found in the comment at top of this
file.
Thanks,
Paul Bolle
A suggestion to your correction.
If you won't to say: "You have a mismatch between header and
MODULE_LICENSE, please make sure it will match."
You saying some thing like this: "I was right last time. Make module
License like I saying."
I'm confuse, what is your actual point? Do you trying to prove some thing?
Am 06.04.2015 um 09:42 schrieb Paul Bolle:
> A license nit follows.
>
> On Sun, 2015-04-05 at 08:26 +0200, Oleksij Rempel wrote:
>> --- /dev/null
>> +++ b/drivers/pinctrl/pinctrl-asm9260.c
>> @@ -0,0 +1,733 @@
>> +/*
>> + * Pinctrl driver for the Alphascale ASM9260 SoC
>> + *
>> + * Copyright (c) 2014, Oleksij Rempel <[email protected]>
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms and conditions of the GNU General Public License,
>> + * version 2, as published by the Free Software Foundation.
>> + */
>
> This states the license of this file is GPL v2.
>
>> +MODULE_LICENSE("GPL");
>
> Your reading of include/linux/module.h (see
> https://lkml.org/lkml/2015/4/5/7 ) is incorrect. Because according to
> that header "GPL" means
> GNU Public License v2 or later
>
> while "GPL v2" means
> GNU Public License v2
>
> So only "GPL v2" matches what's found in the comment at top of this
> file.
>
> Thanks,
>
>
> Paul Bolle
>
--
Regards,
Oleksij
changes:
- v4. As Paul Bolle sugested, fixing License in the header.
Oleksij Rempel (2):
pinctrl: Add driver for Alphascale asm9260 pinctrl
pinctrl: asm9260: add pinctrl add device tree bindings documentation
.../pinctrl/alphascale,asm9260-pinctrl.txt | 76 +++
drivers/pinctrl/Kconfig | 8 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/pinctrl-asm9260.c | 733 +++++++++++++++++++++
4 files changed, 818 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pinctrl/alphascale,asm9260-pinctrl.txt
create mode 100644 drivers/pinctrl/pinctrl-asm9260.c
--
1.9.1
This patch adds driver for Alphascale asm9260 pinctrl support.
Alphascale asm9260t is SoC based on ARM926EJ (240MHz) in LQFP176 package.
On silicon are:
- 32MB SDRAM
- USB2.0 HS/OTG
- 2x CAN
- SD/MMC
- 5x Times/PWM
- 10x USART
- 24-channel DMA
- 2x i2c
- 2x SPI
- Quad SPI
- 10/100 Ethernet MAC
- Camera IF
- WD
- RTC
- i2s
- GPIO
- 12-bit A/D
- LCD IF
- 8-channel 12-bit ADC
- NAND
Signed-off-by: Oleksij Rempel <[email protected]>
---
drivers/pinctrl/Kconfig | 8 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/pinctrl-asm9260.c | 733 ++++++++++++++++++++++++++++++++++++++
3 files changed, 742 insertions(+)
create mode 100644 drivers/pinctrl/pinctrl-asm9260.c
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index d014f22..054ecbc 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -47,6 +47,14 @@ config PINCTRL_AS3722
open drain configuration for the GPIO pins of AS3722 devices. It also
supports the GPIO functionality through gpiolib.
+config PINCTRL_ASM9260
+ tristate "Pinctrl driver for Alphascale asm9260"
+ depends on MACH_ASM9260
+ select PINMUX
+ select GENERIC_PINCONF
+ help
+ Say Y here to enable the Alphascale asm9260 pinctrl driver
+
config PINCTRL_BF54x
def_bool y if BF54x
select PINCTRL_ADI2
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index c030b3d..46ba7d1c 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -11,6 +11,7 @@ endif
obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o
obj-$(CONFIG_PINCTRL_ADI2) += pinctrl-adi2.o
obj-$(CONFIG_PINCTRL_AS3722) += pinctrl-as3722.o
+obj-$(CONFIG_PINCTRL_ASM9260) += pinctrl-asm9260.o
obj-$(CONFIG_PINCTRL_BF54x) += pinctrl-adi2-bf54x.o
obj-$(CONFIG_PINCTRL_BF60x) += pinctrl-adi2-bf60x.o
obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o
diff --git a/drivers/pinctrl/pinctrl-asm9260.c b/drivers/pinctrl/pinctrl-asm9260.c
new file mode 100644
index 0000000..2bd72d1
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-asm9260.c
@@ -0,0 +1,733 @@
+/*
+ * Pinctrl driver for the Alphascale ASM9260 SoC
+ *
+ * Copyright (c) 2014, Oleksij Rempel <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+
+#include "core.h"
+#include "pinctrl-utils.h"
+
+/* pinctrl register */
+#define IOCON_PIO0_0 0x0000
+/* only two modes are supported NONE and PULL UP */
+#define IOCON_MODE_SHIFT 3
+#define IOCON_MODE_MASK (0x3 << IOCON_MODE_SHIFT)
+/* Only GPIO0_* pins support pull up. */
+#define IOCON_MODE_PULL_UP (0x2 << IOCON_MODE_SHIFT)
+/* Only GPIO0_* pins don't support pull down. */
+#define IOCON_MODE_PULL_DOWN (0x1 << IOCON_MODE_SHIFT)
+#define IOCON_MODE_NONE (0x0 << IOCON_MODE_SHIFT)
+/* up to 8 functions per pin */
+#define IOCON_PINMUX_MASK (0x7 << 0)
+
+#define MUX_OFFSET(bank, pin) ((bank) * 32 + (pin) * 4)
+
+enum asm9260_mux {
+ ASM9260_MUX_na = -1,
+
+ ASM9260_MUX_gpio0,
+ ASM9260_MUX_cam0,
+ ASM9260_MUX_can0,
+ ASM9260_MUX_can1,
+ ASM9260_MUX_ct0,
+ ASM9260_MUX_ct1,
+ ASM9260_MUX_ct2,
+ ASM9260_MUX_ct3,
+ ASM9260_MUX_i2c0,
+ ASM9260_MUX_i2c1,
+ ASM9260_MUX_i2s0,
+ ASM9260_MUX_i2s1,
+ ASM9260_MUX_jtag,
+ ASM9260_MUX_lcd0,
+ ASM9260_MUX_lcd_if0,
+ ASM9260_MUX_mc,
+ ASM9260_MUX_mc0,
+ ASM9260_MUX_mii0,
+ ASM9260_MUX_nand0,
+ ASM9260_MUX_outclk,
+ ASM9260_MUX_qei0,
+ ASM9260_MUX_qspi0,
+ ASM9260_MUX_rmii0,
+ ASM9260_MUX_sd0,
+ ASM9260_MUX_spi0,
+ ASM9260_MUX_spi1,
+ ASM9260_MUX_uart0,
+ ASM9260_MUX_uart1,
+ ASM9260_MUX_uart2,
+ ASM9260_MUX_uart3,
+ ASM9260_MUX_uart4,
+ ASM9260_MUX_uart5,
+ ASM9260_MUX_uart6,
+ ASM9260_MUX_uart7,
+ ASM9260_MUX_uart8,
+ ASM9260_MUX_uart9,
+};
+
+struct asm9260_function {
+ const char *name;
+ const char **groups;
+ unsigned int ngroups;
+};
+
+#define FUNCTION(mux) \
+ [(ASM9260_MUX_ ## mux)] = { \
+ .name = #mux, \
+ .groups = NULL, \
+ .ngroups = 0, \
+ }
+
+static struct asm9260_function asm9260_functions[] = {
+ FUNCTION(gpio0),
+ FUNCTION(cam0),
+ FUNCTION(can0),
+ FUNCTION(can1),
+ FUNCTION(ct0),
+ FUNCTION(ct1),
+ FUNCTION(ct2),
+ FUNCTION(ct3),
+ FUNCTION(i2c0),
+ FUNCTION(i2c1),
+ FUNCTION(i2s0),
+ FUNCTION(i2s1),
+ FUNCTION(jtag),
+ FUNCTION(lcd0),
+ FUNCTION(lcd_if0),
+ FUNCTION(mc),
+ FUNCTION(mc0),
+ FUNCTION(mii0),
+ FUNCTION(nand0),
+ FUNCTION(outclk),
+ FUNCTION(qei0),
+ FUNCTION(qspi0),
+ FUNCTION(rmii0),
+ FUNCTION(sd0),
+ FUNCTION(spi0),
+ FUNCTION(spi1),
+ FUNCTION(uart0),
+ FUNCTION(uart1),
+ FUNCTION(uart2),
+ FUNCTION(uart3),
+ FUNCTION(uart4),
+ FUNCTION(uart5),
+ FUNCTION(uart6),
+ FUNCTION(uart7),
+ FUNCTION(uart8),
+ FUNCTION(uart9),
+};
+
+struct asm9260_pingroup {
+ const char *name;
+ const unsigned int number;
+ const unsigned int bank;
+ const unsigned int pin;
+
+#define MAX_FUNCS_PER_PIN 8
+ const int funcs[MAX_FUNCS_PER_PIN];
+};
+
+#define PMUX(p_number, p_bank, p_pin, p_name, f1, f2, f3, f4, f5, f6, f7) \
+ { \
+ .number = p_number, \
+ .bank = p_bank, \
+ .pin = p_pin, \
+ .name = #p_name, \
+ .funcs = { \
+ ASM9260_MUX_gpio0, \
+ ASM9260_MUX_ ## f1, \
+ ASM9260_MUX_ ## f2, \
+ ASM9260_MUX_ ## f3, \
+ ASM9260_MUX_ ## f4, \
+ ASM9260_MUX_ ## f5, \
+ ASM9260_MUX_ ## f6, \
+ ASM9260_MUX_ ## f7, \
+ }, \
+ }
+
+static struct asm9260_pingroup asm9260_mux_table[] = {
+ PMUX(120, 0, 0, GPIO0_0,
+ na, uart1, i2s0, spi1, na, jtag, na),
+ PMUX(121, 0, 1, GPIO0_1,
+ na, uart1, i2s0, spi1, na, jtag, na),
+ PMUX(122, 0, 2, GPIO0_2,
+ na, uart1, i2s0, spi1, na, jtag, na),
+ PMUX(123, 0, 3, GPIO0_3,
+ na, uart1, i2s0, spi1, na, jtag, na),
+ PMUX(124, 0, 4, GPIO0_4,
+ na, uart1, i2s0, spi0, na, jtag, i2c0),
+ PMUX(128, 1, 4, GPIO1_4,
+ ct0, uart0, lcd_if0, spi0, mii0, lcd0, na),
+ PMUX(129, 1, 5, GPIO1_5,
+ na, uart0, lcd_if0, spi0, rmii0, lcd0, na),
+ PMUX(130, 1, 6, GPIO1_6,
+ na, uart0, lcd_if0, spi0, rmii0, lcd0, i2c1),
+ PMUX(131, 1, 7, GPIO1_7,
+ na, uart0, lcd_if0, spi0, rmii0, lcd0, i2c1),
+ PMUX(132, 2, 0, GPIO2_0,
+ ct1, uart2, lcd_if0, spi1, mii0, lcd0, can0),
+ PMUX(133, 2, 1, GPIO2_1,
+ ct1, uart2, lcd_if0, spi1, mii0, lcd0, can0),
+ PMUX(134, 2, 2, GPIO2_2,
+ ct1, uart3, lcd_if0, spi1, mii0, lcd0, na),
+ PMUX(135, 2, 3, GPIO2_3,
+ ct1, uart3, lcd_if0, spi1, mii0, lcd0, na),
+ PMUX(136, 2, 4, GPIO2_4,
+ ct1, uart3, lcd_if0, na, mii0, lcd0, na),
+ PMUX(137, 2, 5, GPIO2_5,
+ na, uart3, lcd_if0, na, mii0, lcd0, outclk),
+ PMUX(138, 2, 6, GPIO2_6,
+ na, uart3, lcd_if0, na, mii0, lcd0, can1),
+ PMUX(139, 2, 7, GPIO2_7,
+ na, uart4, lcd_if0, na, mii0, lcd0, can1),
+ PMUX(140, 3, 0, GPIO3_0,
+ ct2, uart4, lcd_if0, sd0, rmii0, lcd0, na),
+ PMUX(141, 3, 1, GPIO3_1,
+ ct2, uart4, lcd_if0, sd0, rmii0, lcd0, na),
+ PMUX(142, 3, 2, GPIO3_2,
+ ct2, uart4, lcd_if0, sd0, rmii0, lcd0, can1),
+ PMUX(143, 3, 3, GPIO3_3,
+ ct2, uart4, lcd_if0, sd0, rmii0, lcd0, can1),
+ PMUX(144, 3, 4, GPIO3_4,
+ ct2, uart5, lcd_if0, sd0, rmii0, lcd0, outclk),
+ PMUX(145, 3, 5, GPIO3_5,
+ na, uart5, lcd_if0, sd0, rmii0, lcd0, i2c0),
+ PMUX(146, 3, 6, GPIO3_6,
+ na, uart5, lcd_if0, na, rmii0, lcd0, i2c0),
+ PMUX(147, 3, 7, GPIO3_7,
+ na, uart5, lcd_if0, na, rmii0, lcd0, na),
+ PMUX(151, 4, 0, GPIO4_0,
+ ct3, uart5, na, qspi0, mii0, lcd0, na),
+ PMUX(152, 4, 1, GPIO4_1,
+ ct3, uart6, na, qspi0, mii0, lcd0, na),
+ PMUX(153, 4, 2, GPIO4_2,
+ ct3, uart6, na, qspi0, mii0, lcd0, na),
+ PMUX(154, 4, 3, GPIO4_3,
+ ct3, uart6, na, qspi0, mii0, lcd0, na),
+ PMUX(155, 4, 4, GPIO4_4,
+ ct3, uart6, na, qspi0, mii0, lcd0, na),
+ PMUX(156, 4, 5, GPIO4_5,
+ na, uart6, na, qspi0, mii0, lcd0, na),
+ PMUX(157, 4, 6, GPIO4_6,
+ na, na, na, na, mii0, lcd0, i2c1),
+ PMUX(158, 4, 7, GPIO4_7,
+ na, na, na, na, mii0, lcd0, i2c1),
+ PMUX(169, 5, 0, GPIO5_0,
+ mc0, uart7, i2s1, sd0, rmii0, na, na),
+ PMUX(170, 5, 1, GPIO5_1,
+ mc0, uart7, i2s1, sd0, rmii0, na, na),
+ PMUX(171, 5, 2, GPIO5_2,
+ mc0, uart7, i2s1, sd0, rmii0, na, can0),
+ PMUX(172, 5, 3, GPIO5_3,
+ mc0, uart7, i2s1, sd0, rmii0, na, can0),
+ PMUX(173, 5, 4, GPIO5_4,
+ mc0, uart8, i2s1, sd0, rmii0, na, na),
+ PMUX(51, 8, 1, GPIO8_1,
+ na, uart2, cam0, na, mii0, na, na),
+ PMUX(52, 8, 2, GPIO8_2,
+ na, uart2, cam0, na, mii0, na, na),
+ PMUX(53, 8, 3, GPIO8_3,
+ na, uart2, cam0, na, mii0, na, na),
+ PMUX(54, 8, 4, GPIO8_4,
+ na, uart2, cam0, na, mii0, na, na),
+ PMUX(55, 8, 5, GPIO8_5,
+ na, uart3, cam0, na, mii0, na, na),
+ PMUX(56, 8, 6, GPIO8_6,
+ na, uart3, cam0, na, mii0, na, na),
+ PMUX(57, 8, 7, GPIO8_7,
+ na, uart3, cam0, na, mii0, na, na),
+ PMUX(45, 9, 0, GPIO9_0,
+ ct0, uart3, cam0, na, rmii0, na, i2c0),
+ PMUX(46, 9, 1, GPIO9_1,
+ ct0, uart3, cam0, na, rmii0, na, i2c0),
+ PMUX(47, 9, 2, GPIO9_2,
+ ct0, uart4, cam0, na, rmii0, na, na),
+ PMUX(48, 9, 3, GPIO9_3,
+ ct0, uart4, cam0, na, rmii0, na, na),
+ PMUX(49, 9, 4, GPIO9_4,
+ ct0, uart4, cam0, na, rmii0, na, na),
+ PMUX(50, 9, 5, GPIO9_5,
+ na, uart4, cam0, na, rmii0, na, i2c1),
+ PMUX(4, 10, 0, GPIO10_0,
+ ct1, uart5, i2s0, spi0, na, na, na),
+ PMUX(5, 10, 1, GPIO10_1,
+ ct1, uart5, i2s0, spi0, rmii0, na, na),
+ PMUX(6, 10, 2, GPIO10_2,
+ ct1, uart5, i2s0, spi0, rmii0, na, na),
+ PMUX(7, 10, 3, GPIO10_3,
+ ct1, uart5, i2s0, spi0, na, na, can0),
+ PMUX(8, 10, 4, GPIO10_4,
+ ct1, uart6, i2s0, spi1, rmii0, na, na),
+ PMUX(9, 10, 5, GPIO10_5,
+ na, uart6, i2s0, spi1, rmii0, na, can1),
+ PMUX(10, 10, 6, GPIO10_6,
+ na, uart6, i2s0, spi1, rmii0, na, can1),
+ PMUX(11, 10, 7, GPIO10_7,
+ na, uart6, cam0, spi1, rmii0, na, na),
+ PMUX(12, 11, 0, GPIO11_0,
+ ct2, uart7, i2s1, qspi0, nand0, na, na),
+ PMUX(13, 11, 1, GPIO11_1,
+ ct2, uart7, i2s1, qspi0, nand0, na, na),
+ PMUX(14, 11, 2, GPIO11_2,
+ ct2, uart7, i2s1, qspi0, nand0, na, na),
+ PMUX(15, 11, 3, GPIO11_3,
+ ct2, uart7, i2s1, qspi0, nand0, na, na),
+ PMUX(16, 11, 4, GPIO11_4,
+ ct2, uart8, i2s1, qspi0, nand0, na, na),
+ PMUX(17, 11, 5, GPIO11_5,
+ na, uart8, i2s1, qspi0, nand0, na, na),
+ PMUX(18, 11, 6, GPIO11_6,
+ na, uart9, i2s1, na, nand0, na, i2c0),
+ PMUX(19, 11, 7, GPIO11_7,
+ na, uart9, cam0, na, nand0, na, i2c0),
+ PMUX(23, 12, 0, GPIO12_0,
+ ct3, uart1, na, sd0, nand0, na, na),
+ PMUX(24, 12, 1, GPIO12_1,
+ ct3, uart1, na, sd0, nand0, na, na),
+ PMUX(25, 12, 2, GPIO12_2,
+ ct3, uart1, na, sd0, nand0, na, na),
+ PMUX(26, 12, 3, GPIO12_3,
+ ct3, uart1, na, sd0, nand0, na, na),
+ PMUX(27, 12, 4, GPIO12_4,
+ ct3, uart1, na, sd0, nand0, na, na),
+ PMUX(28, 12, 5, GPIO12_5,
+ na, uart8, na, sd0, nand0, na, na),
+ PMUX(29, 12, 6, GPIO12_6,
+ na, uart8, cam0, na, nand0, na, i2c1),
+ PMUX(30, 12, 7, GPIO12_7,
+ na, na, cam0, na, nand0, na, i2c1),
+ PMUX(31, 13, 4, GPIO13_4,
+ mc, uart2, na, spi1, nand0, na, na),
+ PMUX(32, 13, 5, GPIO13_5,
+ mc0, uart9, na, spi1, nand0, na, na),
+ PMUX(33, 13, 6, GPIO13_6,
+ mc0, uart9, na, spi1, nand0, na, na),
+ PMUX(34, 13, 7, GPIO13_7,
+ mc0, na, na, spi1, nand0, na, na),
+ PMUX(38, 14, 0, GPIO14_0,
+ mc0, uart0, i2s0, sd0, nand0, na, na),
+ PMUX(39, 14, 1, GPIO14_1,
+ mc0, uart0, i2s0, sd0, nand0, na, na),
+ PMUX(40, 14, 2, GPIO14_2,
+ na, uart0, i2s0, sd0, nand0, na, na),
+ PMUX(41, 14, 3, GPIO14_3,
+ na, uart0, i2s0, sd0, nand0, na, na),
+ PMUX(42, 14, 4, GPIO14_4,
+ na, uart0, i2s0, sd0, nand0, na, na),
+ PMUX(43, 14, 5, GPIO14_5,
+ na, uart0, i2s0, sd0, nand0, na, na),
+ PMUX(44, 15, 0, GPIO15_0,
+ na, uart4, i2s0, sd0, rmii0, na, na),
+ PMUX(61, 15, 1, GPIO15_1,
+ na, uart4, i2s0, sd0, rmii0, na, na),
+ PMUX(62, 15, 2, GPIO15_2,
+ na, uart5, i2s0, sd0, rmii0, na, na),
+ PMUX(63, 15, 3, GPIO15_3,
+ na, uart5, i2s0, sd0, rmii0, na, na),
+ PMUX(64, 15, 4, GPIO15_4,
+ na, uart6, i2s0, sd0, rmii0, na, na),
+ PMUX(65, 15, 5, GPIO15_5,
+ na, uart6, i2s0, sd0, rmii0, na, na),
+ PMUX(66, 15, 6, GPIO15_6,
+ na, uart7, i2s0, na, rmii0, na, na),
+ PMUX(67, 15, 7, GPIO15_7,
+ na, uart7, na, na, rmii0, na, na),
+ PMUX(73, 16, 0, GPIO16_0,
+ ct2, uart4, na, na, mii0, na, na),
+ PMUX(74, 16, 1, GPIO16_1,
+ ct2, uart4, na, na, mii0, na, na),
+ PMUX(75, 16, 2, GPIO16_2,
+ ct2, uart5, na, na, mii0, na, na),
+ PMUX(76, 16, 3, GPIO16_3,
+ ct2, uart5, na, na, mii0, na, na),
+ PMUX(77, 16, 4, GPIO16_4,
+ ct2, uart6, na, na, mii0, na, na),
+ PMUX(78, 16, 5, GPIO16_5,
+ qei0, uart6, na, na, mii0, na, na),
+ PMUX(79, 16, 6, GPIO16_6,
+ qei0, uart6, na, na, mii0, na, can1),
+ PMUX(80, 16, 7, GPIO16_7,
+ qei0, uart6, na, na, mii0, na, can1),
+ PMUX(81, 17, 0, GPIO17_0,
+ ct3, uart7, i2s1, na, rmii0, na, na),
+ PMUX(82, 17, 1, GPIO17_1,
+ ct3, uart7, i2s1, na, na, na, na),
+ PMUX(83, 17, 2, GPIO17_2,
+ ct3, uart7, i2s1, na, na, na, i2c1),
+ PMUX(84, 17, 3, GPIO17_3,
+ ct3, uart7, i2s1, na, na, na, i2c1),
+ PMUX(85, 17, 4, GPIO17_4,
+ ct3, uart8, i2s1, na, na, na, na),
+ PMUX(86, 17, 5, GPIO17_5,
+ qei0, uart8, i2s1, na, rmii0, na, na),
+ PMUX(87, 17, 6, GPIO17_6,
+ qei0, uart9, i2s1, na, mii0, na, na),
+ PMUX(88, 17, 7, GPIO17_7,
+ qei0, uart9, na, na, mii0, na, na),
+};
+
+#define MUX_TABLE_SIZE ARRAY_SIZE(asm9260_mux_table)
+struct asm9260_pmx_priv {
+ struct device *dev;
+ struct pinctrl_dev *pctl;
+ void __iomem *iobase;
+
+ struct clk *clk;
+ spinlock_t lock;
+
+ struct pinctrl_pin_desc pin_desc[MUX_TABLE_SIZE];
+};
+
+static void __init asm9260_init_mux_pins(struct asm9260_pmx_priv *priv)
+{
+ unsigned int i;
+
+ for (i = 0; i < MUX_TABLE_SIZE; i++) {
+ priv->pin_desc[i].name = asm9260_mux_table[i].name;
+ priv->pin_desc[i].number = asm9260_mux_table[i].number;
+ }
+}
+
+/*
+ * Pin control operations
+ */
+
+/* each GPIO pin has it's own pseudo pingroup containing only itself */
+static int asm9260_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+ return MUX_TABLE_SIZE;
+}
+
+static const char *asm9260_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
+ unsigned int group)
+{
+ struct asm9260_pmx_priv *priv = pinctrl_dev_get_drvdata(pctldev);
+
+ return priv->pin_desc[group].name;
+}
+
+static int asm9260_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+ unsigned int group,
+ const unsigned int **pins,
+ unsigned int *num_pins)
+{
+ struct asm9260_pmx_priv *priv = pinctrl_dev_get_drvdata(pctldev);
+
+ *pins = &priv->pin_desc[group].number;
+ *num_pins = 1;
+
+ return 0;
+}
+
+static struct pinctrl_ops asm9260_pinctrl_ops = {
+ .get_groups_count = asm9260_pinctrl_get_groups_count,
+ .get_group_name = asm9260_pinctrl_get_group_name,
+ .get_group_pins = asm9260_pinctrl_get_group_pins,
+ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
+ .dt_free_map = pinctrl_utils_dt_free_map,
+};
+
+/*
+ * Pin mux operations
+ */
+static int asm9260_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
+{
+ return ARRAY_SIZE(asm9260_functions);
+}
+
+static const char *asm9260_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
+ unsigned int function)
+{
+ return asm9260_functions[function].name;
+}
+
+static int asm9260_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
+ unsigned int function,
+ const char * const **groups,
+ unsigned int * const num_groups)
+{
+ struct asm9260_pmx_priv *priv = pinctrl_dev_get_drvdata(pctldev);
+ struct asm9260_pingroup *table;
+ int a, b, count = 0, *tmp;
+ const char **gr;
+
+ if (asm9260_functions[function].groups != NULL)
+ goto done;
+
+ tmp = devm_kmalloc(priv->dev, sizeof(tmp) * MUX_TABLE_SIZE, GFP_KERNEL);
+ if (!tmp) {
+ dev_err(priv->dev, "Can't allocate func/pin array\n");
+ return PTR_ERR(tmp);
+ }
+
+ for (a = 0; a < MUX_TABLE_SIZE; a++) {
+ table = &asm9260_mux_table[a];
+
+ for (b = 0; b < MAX_FUNCS_PER_PIN; b++) {
+ if (table->funcs[b] == function) {
+ tmp[count] = a;
+ count++;
+ }
+
+ }
+
+ }
+
+ gr = devm_kmalloc(priv->dev,
+ sizeof(gr) * count, GFP_KERNEL);
+ if (!gr) {
+ dev_err(priv->dev, "Can't allocate func group\n");
+ devm_kfree(priv->dev, tmp);
+ return PTR_ERR(gr);
+ }
+
+ for (a = 0; a < count; a++)
+ gr[a] = asm9260_mux_table[tmp[a]].name;
+
+ asm9260_functions[function].groups = gr;
+ asm9260_functions[function].ngroups = count;
+done:
+ *groups = asm9260_functions[function].groups;
+ *num_groups = asm9260_functions[function].ngroups;
+ return 0;
+}
+
+static int asm9260_pinctrl_set_mux(struct pinctrl_dev *pctldev,
+ unsigned int function, unsigned int pin)
+{
+ struct asm9260_pmx_priv *priv = pinctrl_dev_get_drvdata(pctldev);
+ struct asm9260_pingroup *table;
+ void __iomem *offset;
+ int mux;
+ u32 val;
+
+ table = &asm9260_mux_table[pin];
+ for (mux = 0; mux < MAX_FUNCS_PER_PIN; ++mux) {
+ if (table->funcs[mux] == function)
+ goto found_mux;
+ }
+
+ return -EINVAL;
+
+found_mux:
+ offset = priv->iobase + MUX_OFFSET(table->bank, table->pin);
+ spin_lock(&priv->lock);
+ val = ioread32(offset);
+ val &= ~IOCON_PINMUX_MASK;
+ val |= mux;
+ iowrite32(val, offset);
+ spin_unlock(&priv->lock);
+
+ return 0;
+}
+
+static struct pinmux_ops asm9260_pinmux_ops = {
+ .get_functions_count = asm9260_pinctrl_get_funcs_count,
+ .get_function_name = asm9260_pinctrl_get_func_name,
+ .get_function_groups = asm9260_pinctrl_get_func_groups,
+ .set_mux = asm9260_pinctrl_set_mux,
+ /* TODO: should we care about gpios here? gpio_request_enable? */
+};
+
+static int asm9260_pinconf_reg(struct pinctrl_dev *pctldev,
+ unsigned int pin,
+ enum pin_config_param param,
+ void __iomem **reg, u32 *val)
+{
+ struct asm9260_pmx_priv *priv = pinctrl_dev_get_drvdata(pctldev);
+ struct asm9260_pingroup *table;
+ int a;
+
+ for (a = 0; a < MUX_TABLE_SIZE; a++) {
+ table = &asm9260_mux_table[a];
+ if (table->number == pin)
+ break;
+ }
+
+ *reg = priv->iobase + MUX_OFFSET(table->bank, table->pin);
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ *val = IOCON_MODE_NONE;
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ if (table->bank != 0)
+ return -ENOTSUPP;
+ *val = IOCON_MODE_PULL_UP;
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ if (table->bank == 0)
+ return -ENOTSUPP;
+ *val = IOCON_MODE_PULL_DOWN;
+ break;
+ default:
+ return -ENOTSUPP;
+ };
+
+ return 0;
+}
+
+static int asm9260_pinconf_get(struct pinctrl_dev *pctldev,
+ unsigned int pin, unsigned long *config)
+{
+ enum pin_config_param param = pinconf_to_config_param(*config);
+ void __iomem *reg;
+ u32 val, tmp, arg;
+ int ret;
+
+ /* Get register information */
+ ret = asm9260_pinconf_reg(pctldev, pin, param,
+ ®, &val);
+ if (ret < 0)
+ return ret;
+
+ /* Extract field from register */
+ tmp = ioread32(reg);
+ arg = (tmp & IOCON_MODE_MASK) == val;
+ if (!arg)
+ return -EINVAL;
+
+ /* And pack config */
+ *config = pinconf_to_config_packed(param, arg);
+
+ return 0;
+}
+
+static int asm9260_pinconf_set(struct pinctrl_dev *pctldev,
+ unsigned int pin, unsigned long *configs,
+ unsigned num_configs)
+{
+ struct asm9260_pmx_priv *priv = pinctrl_dev_get_drvdata(pctldev);
+ enum pin_config_param param;
+ unsigned int arg;
+ int ret;
+ u32 val, tmp;
+ void __iomem *reg;
+ int i;
+
+ for (i = 0; i < num_configs; i++) {
+ param = pinconf_to_config_param(configs[i]);
+ arg = pinconf_to_config_argument(configs[i]);
+
+ /* Get register information */
+ ret = asm9260_pinconf_reg(pctldev, pin, param,
+ ®, &val);
+ if (ret < 0)
+ return ret;
+
+ spin_lock(&priv->lock);
+ tmp = ioread32(reg);
+ tmp &= ~IOCON_MODE_MASK;
+ if (arg)
+ tmp |= val;
+ iowrite32(tmp, reg);
+ spin_unlock(&priv->lock);
+ }
+
+ return 0;
+}
+
+static struct pinconf_ops asm9260_pinconf_ops = {
+ .is_generic = true,
+ .pin_config_get = asm9260_pinconf_get,
+ .pin_config_set = asm9260_pinconf_set,
+};
+
+/*
+ * Pin control driver setup
+ */
+static struct pinctrl_desc asm9260_pinctrl_desc = {
+ .pctlops = &asm9260_pinctrl_ops,
+ .pmxops = &asm9260_pinmux_ops,
+ .confops = &asm9260_pinconf_ops,
+ .owner = THIS_MODULE,
+};
+
+static int asm9260_pinctrl_probe(struct platform_device *pdev)
+{
+ struct asm9260_pmx_priv *priv;
+ struct resource *res;
+ int ret;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv) {
+ dev_err(&pdev->dev, "Can't alloc asm9260_priv\n");
+ return -ENOMEM;
+ }
+ priv->dev = &pdev->dev;
+ spin_lock_init(&priv->lock);
+
+ asm9260_init_mux_pins(priv);
+
+ asm9260_pinctrl_desc.name = dev_name(&pdev->dev);
+ asm9260_pinctrl_desc.pins = priv->pin_desc;
+ asm9260_pinctrl_desc.npins = MUX_TABLE_SIZE;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ priv->iobase = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(priv->iobase))
+ return PTR_ERR(priv->iobase);
+
+ priv->clk = devm_clk_get(&pdev->dev, "ahb");
+ ret = clk_prepare_enable(priv->clk);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to enable clk!\n");
+ return ret;
+ }
+
+ priv->pctl = pinctrl_register(&asm9260_pinctrl_desc, &pdev->dev, priv);
+ if (!priv->pctl) {
+ dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
+ ret = -ENODEV;
+ goto err_return;
+ }
+
+ platform_set_drvdata(pdev, priv);
+
+ dev_info(&pdev->dev, "ASM9260 pinctrl driver initialised\n");
+
+ return 0;
+err_return:
+ clk_disable_unprepare(priv->clk);
+ return ret;
+}
+
+static int asm9260_pinctrl_remove(struct platform_device *pdev)
+{
+ struct asm9260_pmx_priv *priv = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(priv->clk);
+ pinctrl_unregister(priv->pctl);
+
+ return 0;
+}
+
+static struct of_device_id asm9260_pinctrl_of_match[] = {
+ { .compatible = "alphascale,asm9260-pinctrl", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, asm9260_pinctrl_of_match);
+
+static struct platform_driver asm9260_pinctrl_driver = {
+ .driver = {
+ .name = "asm9260-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = asm9260_pinctrl_of_match,
+ },
+ .probe = asm9260_pinctrl_probe,
+ .remove = asm9260_pinctrl_remove,
+};
+module_platform_driver(asm9260_pinctrl_driver);
+
+MODULE_AUTHOR("Oleksij Rempel <[email protected]>");
+MODULE_DESCRIPTION("Alphascale ASM9260 pinctrl driver");
+MODULE_LICENSE("GPL");
--
1.9.1
Add device tree bindings documentation for Alphascale asm9260 pin controller
Signed-off-by: Oleksij Rempel <[email protected]>
---
.../pinctrl/alphascale,asm9260-pinctrl.txt | 76 ++++++++++++++++++++++
1 file changed, 76 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pinctrl/alphascale,asm9260-pinctrl.txt
diff --git a/Documentation/devicetree/bindings/pinctrl/alphascale,asm9260-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/alphascale,asm9260-pinctrl.txt
new file mode 100644
index 0000000..dbeea4d
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/alphascale,asm9260-pinctrl.txt
@@ -0,0 +1,76 @@
+* Alphascale ASM9260 SoC pinctrl core driver
+
+The pinctrl driver enables Alphascale ASM9260 to configure pin multiplexing
+to a specific function.
+
+Required properties for pinctrl driver:
+- compatible: "alphascale,asm9260-pinctrl"
+- reg: Register base of the MPP block and length.
+- clocks: clock ids.
+- clock-names:
+ * 1 "ahb" : AHB gating clock.
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices, including the meaning of the
+phrase "pin configuration node".
+
+The pin configuration nodes act as a container for an arbitrary number of
+subnodes. Each of these subnodes represents some desired configuration for a
+pin or a list of pins. This configuration can include the
+mux function to select on those pin(s), and various pin configuration
+parameters, as listed below.
+
+SUBNODES:
+
+The name of each subnode is not important; all subnodes should be enumerated
+and processed purely based on their content.
+
+Each subnode only affects those parameters that are explicitly listed. In
+other words, a subnode that lists a mux function but no pin configuration
+parameters implies no information about any pin configuration parameters.
+Similarly, a pin subnode that describes a pullup parameter implies no
+information about e.g. the mux function.
+
+The following generic properties as defined in pinctrl-bindings.txt are valid
+to specify in a pin configuration subnode:
+pins - the list of pins that properties in the node
+ apply to (either this or "groups" has to be
+ specified)
+function - the mux function to select
+bias-disable - disable any pin bias
+bias-pull-up - pull up the pin. Supported only on GPIO0_* pins.
+bias-pull-down - pull down the pin. Supported on all pins except of GPIO0_*.
+
+Examples:
+
+pinctrl: pinctrl@80044000 {
+ compatible = "alphascale,asm9260-pinctrl";
+ reg = <0x80044000 0x400>;
+ clocks = <&acc CLKID_AHB_IOCONFIG>;
+ clock-names = "ahb";
+
+ nand_fc0_pins_a: nand_fc0 {
+ nand_main_gr {
+ pins = "GPIO11_0", "GPIO11_1", "GPIO11_2",
+ "GPIO11_3", "GPIO11_4", "GPIO11_6",
+ "GPIO12_0", "GPIO12_1", "GPIO12_2",
+ "GPIO12_3", "GPIO12_4", "GPIO12_5",
+ "GPIO12_6", "GPIO12_7";
+ function = "nand0";
+ bias-disable;
+ };
+ };
+};
+
+nand_controller0 {
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ nand-ecc-strength = <4>;
+ nand-ecc-step-size = <512>;
+ nand-max-chips = <1>;
+ nand-on-flash-bbt;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&nand_fc0_pins_a>;
+};
--
1.9.1
On Mon, 2015-04-06 at 10:38 +0200, Oleksij Rempel wrote:
> If you won't to say: "You have a mismatch between header and
> MODULE_LICENSE, please make sure it will match."
> You saying some thing like this: "I was right last time. Make module
> License like I saying."
No, that's not what I wrote.
> I'm confuse, what is your actual point? Do you trying to prove some thing?
My point is that there's a mismatch between the license described in the
comment at the top of this file and the ident used in the
MODULE_LICENSE() macro. In my comments on v2 I wrote:
By the way, you probably want to use "GPL v2" as the license ident
[...].
In this v3 I noticed the same mismatch (which was not surprising because
you already stated that "GPL" actually did match what's stated at the
comment in the top of this file). Therefor I wrote:
So only "GPL v2" matches what's found in the comment at top of this
file.
There now seem to be a few options:
- change either the comment at the top of this file or the license ident
used in MODULE_LICENSE() to make them actually match;
- show that I misread the comment at top of this file;
- or show that my reading of module.h is incorrect.
(Another option would be a patch that somehow merges the "GPL" and "GPL
v2" license idents. That patch would put an end to discussions like the
one we're having here. I'm _not_ volunteering to submit it.)
Thanks,
Paul Bolle
Am 06.04.2015 um 11:41 schrieb Paul Bolle:
> On Mon, 2015-04-06 at 10:38 +0200, Oleksij Rempel wrote:
>> If you won't to say: "You have a mismatch between header and
>> MODULE_LICENSE, please make sure it will match."
>> You saying some thing like this: "I was right last time. Make module
>> License like I saying."
>
> No, that's not what I wrote.
>
>> I'm confuse, what is your actual point? Do you trying to prove some thing?
>
> My point is that there's a mismatch between the license described in the
> comment at the top of this file and the ident used in the
> MODULE_LICENSE() macro. In my comments on v2 I wrote:
> By the way, you probably want to use "GPL v2" as the license ident
> [...].
>
> In this v3 I noticed the same mismatch (which was not surprising because
> you already stated that "GPL" actually did match what's stated at the
> comment in the top of this file). Therefor I wrote:
> So only "GPL v2" matches what's found in the comment at top of this
> file.
>
> There now seem to be a few options:
> - change either the comment at the top of this file or the license ident
> used in MODULE_LICENSE() to make them actually match;
> - show that I misread the comment at top of this file;
> - or show that my reading of module.h is incorrect.
Ok, thank you for your review.
i send new version of patch with fixing header license to "v2 and later".
> (Another option would be a patch that somehow merges the "GPL" and "GPL
> v2" license idents. That patch would put an end to discussions like the
> one we're having here. I'm _not_ volunteering to submit it.)
>
> Thanks,
>
>
> Paul Bolle
>
--
Regards,
Oleksij
Hallo all,
any updates here? :D
Am 06.04.2015 um 11:04 schrieb Oleksij Rempel:
> changes:
> - v4. As Paul Bolle sugested, fixing License in the header.
>
> Oleksij Rempel (2):
> pinctrl: Add driver for Alphascale asm9260 pinctrl
> pinctrl: asm9260: add pinctrl add device tree bindings documentation
>
> .../pinctrl/alphascale,asm9260-pinctrl.txt | 76 +++
> drivers/pinctrl/Kconfig | 8 +
> drivers/pinctrl/Makefile | 1 +
> drivers/pinctrl/pinctrl-asm9260.c | 733 +++++++++++++++++++++
> 4 files changed, 818 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/pinctrl/alphascale,asm9260-pinctrl.txt
> create mode 100644 drivers/pinctrl/pinctrl-asm9260.c
>
--
Regards,
Oleksij
On Wed, Apr 22, 2015 at 9:49 PM, Oleksij Rempel <[email protected]> wrote:
> Hallo all,
>
> any updates here? :D
Sorry for the delay. Merge window you know.
Looking at it now.
Yours,
Linus Walleij
On Mon, Apr 6, 2015 at 11:04 AM, Oleksij Rempel <[email protected]> wrote:
> Add device tree bindings documentation for Alphascale asm9260 pin controller
>
> Signed-off-by: Oleksij Rempel <[email protected]>
(...)
> +* Alphascale ASM9260 SoC pinctrl core driver
> +
> +The pinctrl driver enables Alphascale ASM9260 to configure pin multiplexing
> +to a specific function.
> +
> +Required properties for pinctrl driver:
> +- compatible: "alphascale,asm9260-pinctrl"
> +- reg: Register base of the MPP block and length.
> +- clocks: clock ids.
> +- clock-names:
> + * 1 "ahb" : AHB gating clock.
This clock is usually called pclock, "apb_pclk" (amba peripheral bus
p clock, don't know what P is...) what name does this have on your
data sheet?
> +The following generic properties as defined in pinctrl-bindings.txt are valid
> +to specify in a pin configuration subnode:
> +pins - the list of pins that properties in the node
> + apply to (either this or "groups" has to be
> + specified)
> +function - the mux function to select
> +bias-disable - disable any pin bias
> +bias-pull-up - pull up the pin. Supported only on GPIO0_* pins.
> +bias-pull-down - pull down the pin. Supported on all pins except of GPIO0_*.
Generic bindings, nice. Put a reference to the file pinctrl-bindings.txt
to point this out.
Yours,
Linus Walleij
On Mon, Apr 6, 2015 at 11:04 AM, Oleksij Rempel <[email protected]> wrote:
> This patch adds driver for Alphascale asm9260 pinctrl support.
> Alphascale asm9260t is SoC based on ARM926EJ (240MHz) in LQFP176 package.
> On silicon are:
> - 32MB SDRAM
> - USB2.0 HS/OTG
> - 2x CAN
> - SD/MMC
> - 5x Times/PWM
> - 10x USART
> - 24-channel DMA
> - 2x i2c
> - 2x SPI
> - Quad SPI
> - 10/100 Ethernet MAC
> - Camera IF
> - WD
> - RTC
> - i2s
> - GPIO
> - 12-bit A/D
> - LCD IF
> - 8-channel 12-bit ADC
> - NAND
>
> Signed-off-by: Oleksij Rempel <[email protected]>
Nice.
> +#define MUX_TABLE_SIZE ARRAY_SIZE(asm9260_mux_table)
> +struct asm9260_pmx_priv {
> + struct device *dev;
> + struct pinctrl_dev *pctl;
> + void __iomem *iobase;
> +
> + struct clk *clk;
> + spinlock_t lock;
> +
> + struct pinctrl_pin_desc pin_desc[MUX_TABLE_SIZE];
> +};
> +
> +static void __init asm9260_init_mux_pins(struct asm9260_pmx_priv *priv)
> +{
> + unsigned int i;
> +
> + for (i = 0; i < MUX_TABLE_SIZE; i++) {
> + priv->pin_desc[i].name = asm9260_mux_table[i].name;
> + priv->pin_desc[i].number = asm9260_mux_table[i].number;
> + }
> +}
What is the point of copying this data from one array to the other?
Just reference the statically defined array by a pointer instead,
this just takes up a lot o memory for no reason.
> +/* each GPIO pin has it's own pseudo pingroup containing only itself */
> +static int asm9260_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
> +{
> + return MUX_TABLE_SIZE;
> +}
Use return ARRAY_SIZE(foo) to return the size of a static table.
> +static int asm9260_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
> + unsigned int group,
> + const unsigned int **pins,
> + unsigned int *num_pins)
> +{
> + struct asm9260_pmx_priv *priv = pinctrl_dev_get_drvdata(pctldev);
> +
> + *pins = &priv->pin_desc[group].number;
> + *num_pins = 1;
So I see you are using groups with one pin each. Is this how the
hardware works?
> +static int asm9260_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
> + unsigned int function,
> + const char * const **groups,
> + unsigned int * const num_groups)
> +{
(...)
> + for (a = 0; a < MUX_TABLE_SIZE; a++) {
> + table = &asm9260_mux_table[a];
> +
> + for (b = 0; b < MAX_FUNCS_PER_PIN; b++) {
> + if (table->funcs[b] == function) {
> + tmp[count] = a;
> + count++;
> + }
> +
> + }
> +
> + }
Mory copying. I don't see why this is necessary at all.
> + for (a = 0; a < count; a++)
> + gr[a] = asm9260_mux_table[tmp[a]].name;
And more copying.
Try to just reference static tables.
> +
> + asm9260_functions[function].groups = gr;
> + asm9260_functions[function].ngroups = count;
> +done:
> + *groups = asm9260_functions[function].groups;
> + *num_groups = asm9260_functions[function].ngroups;
Same comment.
> +static struct pinmux_ops asm9260_pinmux_ops = {
> + .get_functions_count = asm9260_pinctrl_get_funcs_count,
> + .get_function_name = asm9260_pinctrl_get_func_name,
> + .get_function_groups = asm9260_pinctrl_get_func_groups,
> + .set_mux = asm9260_pinctrl_set_mux,
> + /* TODO: should we care about gpios here? gpio_request_enable? */
I think you should, if you also have a matching GPIO driver.
> +static int asm9260_pinconf_reg(struct pinctrl_dev *pctldev,
> + unsigned int pin,
> + enum pin_config_param param,
> + void __iomem **reg, u32 *val)
> +{
> + struct asm9260_pmx_priv *priv = pinctrl_dev_get_drvdata(pctldev);
> + struct asm9260_pingroup *table;
> + int a;
> +
> + for (a = 0; a < MUX_TABLE_SIZE; a++) {
> + table = &asm9260_mux_table[a];
> + if (table->number == pin)
> + break;
> + }
No error check here. What if pin is not in table? We will never
know for that case...
Apart from that it looks OK.
BTW this is a review of v3, I didn't find your v4 of this patch :/
Yours,
Linus Walleij
Am 05.05.2015 um 16:46 schrieb Linus Walleij:
> On Mon, Apr 6, 2015 at 11:04 AM, Oleksij Rempel <[email protected]> wrote:
>
>> Add device tree bindings documentation for Alphascale asm9260 pin controller
>>
>> Signed-off-by: Oleksij Rempel <[email protected]>
>
> (...)
>> +* Alphascale ASM9260 SoC pinctrl core driver
>> +
>> +The pinctrl driver enables Alphascale ASM9260 to configure pin multiplexing
>> +to a specific function.
>> +
>> +Required properties for pinctrl driver:
>> +- compatible: "alphascale,asm9260-pinctrl"
>> +- reg: Register base of the MPP block and length.
>> +- clocks: clock ids.
>> +- clock-names:
>> + * 1 "ahb" : AHB gating clock.
>
> This clock is usually called pclock, "apb_pclk" (amba peripheral bus
> p clock, don't know what P is...) what name does this have on your
> data sheet?
the datasheet uses only "AHB" or "ahb_clk".
Since i use in other modules same name i would prefer to use one style :)
>> +The following generic properties as defined in pinctrl-bindings.txt are valid
>> +to specify in a pin configuration subnode:
>> +pins - the list of pins that properties in the node
>> + apply to (either this or "groups" has to be
>> + specified)
>> +function - the mux function to select
>> +bias-disable - disable any pin bias
>> +bias-pull-up - pull up the pin. Supported only on GPIO0_* pins.
>> +bias-pull-down - pull down the pin. Supported on all pins except of GPIO0_*.
>
> Generic bindings, nice. Put a reference to the file pinctrl-bindings.txt
> to point this out.
Yea, it was already done, see ^^ - "The following generic properties as
defined in pinctrl-bindings.txt" :)
--
Regards,
Oleksij
Am 05.05.2015 um 17:12 schrieb Linus Walleij:
> On Mon, Apr 6, 2015 at 11:04 AM, Oleksij Rempel <[email protected]> wrote:
>
>> This patch adds driver for Alphascale asm9260 pinctrl support.
>> Alphascale asm9260t is SoC based on ARM926EJ (240MHz) in LQFP176 package.
>> On silicon are:
>> - 32MB SDRAM
>> - USB2.0 HS/OTG
>> - 2x CAN
>> - SD/MMC
>> - 5x Times/PWM
>> - 10x USART
>> - 24-channel DMA
>> - 2x i2c
>> - 2x SPI
>> - Quad SPI
>> - 10/100 Ethernet MAC
>> - Camera IF
>> - WD
>> - RTC
>> - i2s
>> - GPIO
>> - 12-bit A/D
>> - LCD IF
>> - 8-channel 12-bit ADC
>> - NAND
>>
>> Signed-off-by: Oleksij Rempel <[email protected]>
>
> Nice.
>
>> +#define MUX_TABLE_SIZE ARRAY_SIZE(asm9260_mux_table)
>> +struct asm9260_pmx_priv {
>> + struct device *dev;
>> + struct pinctrl_dev *pctl;
>> + void __iomem *iobase;
>> +
>> + struct clk *clk;
>> + spinlock_t lock;
>> +
>> + struct pinctrl_pin_desc pin_desc[MUX_TABLE_SIZE];
>> +};
>> +
>> +static void __init asm9260_init_mux_pins(struct asm9260_pmx_priv *priv)
>> +{
>> + unsigned int i;
>> +
>> + for (i = 0; i < MUX_TABLE_SIZE; i++) {
>> + priv->pin_desc[i].name = asm9260_mux_table[i].name;
>> + priv->pin_desc[i].number = asm9260_mux_table[i].number;
>> + }
>> +}
>
> What is the point of copying this data from one array to the other?
>
> Just reference the statically defined array by a pointer instead,
> this just takes up a lot o memory for no reason.
This two arrays have different types this is why i convert it.
priv->pin_desc[i].name - here i copy pointer any ways, and
priv->pin_desc[i].number can be smaller then pointer.
>> +/* each GPIO pin has it's own pseudo pingroup containing only itself */
>> +static int asm9260_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
>> +{
>> + return MUX_TABLE_SIZE;
>> +}
>
> Use return ARRAY_SIZE(foo) to return the size of a static table.
see #define MUX_TABLE_SIZE ARRAY_SIZE(asm9260_mux_table
>> +static int asm9260_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
>> + unsigned int group,
>> + const unsigned int **pins,
>> + unsigned int *num_pins)
>> +{
>> + struct asm9260_pmx_priv *priv = pinctrl_dev_get_drvdata(pctldev);
>> +
>> + *pins = &priv->pin_desc[group].number;
>> + *num_pins = 1;
>
> So I see you are using groups with one pin each. Is this how the
> hardware works?
Yes, each pin can be configured separately.
>> +static int asm9260_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
>> + unsigned int function,
>> + const char * const **groups,
>> + unsigned int * const num_groups)
>> +{
>
> (...)
>> + for (a = 0; a < MUX_TABLE_SIZE; a++) {
>> + table = &asm9260_mux_table[a];
>> +
>> + for (b = 0; b < MAX_FUNCS_PER_PIN; b++) {
>> + if (table->funcs[b] == function) {
>> + tmp[count] = a;
>> + count++;
>> + }
>> +
>> + }
>> +
>> + }
>
> Mory copying. I don't see why this is necessary at all.
I hadn't seen the point to define groups statically, especially because
they are used only to make curious user happy. So, memory will be used
only if you request the list over sysfs. Or miss some thing?
>> + for (a = 0; a < count; a++)
>> + gr[a] = asm9260_mux_table[tmp[a]].name;
>
> And more copying.
>
> Try to just reference static tables.
>
>> +
>> + asm9260_functions[function].groups = gr;
>> + asm9260_functions[function].ngroups = count;
>> +done:
>> + *groups = asm9260_functions[function].groups;
>> + *num_groups = asm9260_functions[function].ngroups;
>
> Same comment.
>
>> +static struct pinmux_ops asm9260_pinmux_ops = {
>> + .get_functions_count = asm9260_pinctrl_get_funcs_count,
>> + .get_function_name = asm9260_pinctrl_get_func_name,
>> + .get_function_groups = asm9260_pinctrl_get_func_groups,
>> + .set_mux = asm9260_pinctrl_set_mux,
>> + /* TODO: should we care about gpios here? gpio_request_enable? */
>
> I think you should, if you also have a matching GPIO driver.
I fear it would cause unpredictable bugs. GPIO mode is just one of mux
modes. If some one will request gpio some busy or dangerous line it
would do more harm then use. So, i assume limiting this only to device
tree would be better.
>
>> +static int asm9260_pinconf_reg(struct pinctrl_dev *pctldev,
>> + unsigned int pin,
>> + enum pin_config_param param,
>> + void __iomem **reg, u32 *val)
>> +{
>> + struct asm9260_pmx_priv *priv = pinctrl_dev_get_drvdata(pctldev);
>> + struct asm9260_pingroup *table;
>> + int a;
>> +
>> + for (a = 0; a < MUX_TABLE_SIZE; a++) {
>> + table = &asm9260_mux_table[a];
>> + if (table->number == pin)
>> + break;
>> + }
>
> No error check here. What if pin is not in table? We will never
> know for that case...
Ok, i agree.
> Apart from that it looks OK.
>
> BTW this is a review of v3, I didn't find your v4 of this patch :/
I'll wait for answers first, then provide next version. Thank you for
review :)
--
Regards,
Oleksij
On Tue, May 12, 2015 at 6:25 PM, Oleksij Rempel <[email protected]> wrote:
> Am 05.05.2015 um 17:12 schrieb Linus Walleij:
>> Just reference the statically defined array by a pointer instead,
>> this just takes up a lot o memory for no reason.
>
> This two arrays have different types this is why i convert it.
> priv->pin_desc[i].name - here i copy pointer any ways, and
> priv->pin_desc[i].number can be smaller then pointer.
I probably do not understand what you're trying to do, sorry :(
Why is it necessary for the driver to copy one description of
the pin into another?
>> Mory copying. I don't see why this is necessary at all.
>
> I hadn't seen the point to define groups statically, especially because
> they are used only to make curious user happy. So, memory will be used
> only if you request the list over sysfs. Or miss some thing?
pinctrl does not even use sysfs.
The group names are usually there for matching with a function,
it is part of the core functionality. The group name + function name
matching is even more obvious in the dt case.
They also make things easier to read in debugfs yes, but
the core of the crux is to make it easy to config function+groups
states with e.g. DT or board files.
>>> +static struct pinmux_ops asm9260_pinmux_ops = {
>>> + .get_functions_count = asm9260_pinctrl_get_funcs_count,
>>> + .get_function_name = asm9260_pinctrl_get_func_name,
>>> + .get_function_groups = asm9260_pinctrl_get_func_groups,
>>> + .set_mux = asm9260_pinctrl_set_mux,
>>> + /* TODO: should we care about gpios here? gpio_request_enable? */
>>
>> I think you should, if you also have a matching GPIO driver.
>
> I fear it would cause unpredictable bugs. GPIO mode is just one of mux
> modes. If some one will request gpio some busy or dangerous line it
> would do more harm then use. So, i assume limiting this only to device
> tree would be better.
Device tree or not doesn't matter, .gpio_request_enable() is used
as a shortcut to mux in GPIO pins.
If the simultaneous use of a pin for a device and GPIO bothers
you there is nowadays (linux-next or my devel branch) a .strict
option in pinmux_ops that you can set to disallow simultaneous
use by devices and GPIO of the same pin.
Yours,
Linus Walleij
Am 13.05.2015 um 13:00 schrieb Linus Walleij:
> On Tue, May 12, 2015 at 6:25 PM, Oleksij Rempel <[email protected]> wrote:
>> Am 05.05.2015 um 17:12 schrieb Linus Walleij:
>
>>> Just reference the statically defined array by a pointer instead,
>>> this just takes up a lot o memory for no reason.
>>
>> This two arrays have different types this is why i convert it.
>> priv->pin_desc[i].name - here i copy pointer any ways, and
>> priv->pin_desc[i].number can be smaller then pointer.
>
> I probably do not understand what you're trying to do, sorry :(
>
> Why is it necessary for the driver to copy one description of
> the pin into another?
>
>>> Mory copying. I don't see why this is necessary at all.
>>
>> I hadn't seen the point to define groups statically, especially because
>> they are used only to make curious user happy. So, memory will be used
>> only if you request the list over sysfs. Or miss some thing?
>
> pinctrl does not even use sysfs.
>
> The group names are usually there for matching with a function,
> it is part of the core functionality. The group name + function name
> matching is even more obvious in the dt case.
>
> They also make things easier to read in debugfs yes, but
> the core of the crux is to make it easy to config function+groups
> states with e.g. DT or board files.
>
>>>> +static struct pinmux_ops asm9260_pinmux_ops = {
>>>> + .get_functions_count = asm9260_pinctrl_get_funcs_count,
>>>> + .get_function_name = asm9260_pinctrl_get_func_name,
>>>> + .get_function_groups = asm9260_pinctrl_get_func_groups,
>>>> + .set_mux = asm9260_pinctrl_set_mux,
>>>> + /* TODO: should we care about gpios here? gpio_request_enable? */
>>>
>>> I think you should, if you also have a matching GPIO driver.
>>
>> I fear it would cause unpredictable bugs. GPIO mode is just one of mux
>> modes. If some one will request gpio some busy or dangerous line it
>> would do more harm then use. So, i assume limiting this only to device
>> tree would be better.
>
> Device tree or not doesn't matter, .gpio_request_enable() is used
> as a shortcut to mux in GPIO pins.
>
> If the simultaneous use of a pin for a device and GPIO bothers
> you there is nowadays (linux-next or my devel branch) a .strict
> option in pinmux_ops that you can set to disallow simultaneous
> use by devices and GPIO of the same pin.
>
> Yours,
> Linus Walleij
>
Hi, you was right, i was blind. Will redo some parts with your suggestions.
--
Regards,
Oleksij