2014-12-04 21:54:11

by Ray Jui

[permalink] [raw]
Subject: [PATCH 0/4] Add pinctrl support to Broadcom Cygnus SoC

This patchset contains the initial pinctrl support for the Broadcom Cygnus SoC.
The Cygnus pinctrl controller supports group based alternate function configuration

Ray Jui (4):
pinctrl: Broadcom Cygnus pinctrl device tree binding
pinctrl: cygnus: add initial pinctrl support
ARM: mach-bcm: enable pinctrl support for Cygnus
ARM: dts: enable pinctrl for Broadcom Cygnus

.../bindings/pinctrl/brcm,cygnus-pinctrl.txt | 92 +++
arch/arm/boot/dts/bcm-cygnus.dtsi | 5 +
arch/arm/mach-bcm/Kconfig | 1 +
drivers/pinctrl/Kconfig | 7 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/pinctrl-bcm-cygnus.c | 753 ++++++++++++++++++++
6 files changed, 859 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinctrl.txt
create mode 100644 drivers/pinctrl/pinctrl-bcm-cygnus.c

--
1.7.9.5


2014-12-04 21:54:25

by Ray Jui

[permalink] [raw]
Subject: [PATCH 1/4] pinctrl: Broadcom Cygnus pinctrl device tree binding

Device tree binding documentation for Broadcom Cygnus pinctrl driver

Signed-off-by: Ray Jui <[email protected]>
Reviewed-by: Scott Branden <[email protected]>
---
.../bindings/pinctrl/brcm,cygnus-pinctrl.txt | 92 ++++++++++++++++++++
1 file changed, 92 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinctrl.txt

diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinctrl.txt
new file mode 100644
index 0000000..86e4579
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinctrl.txt
@@ -0,0 +1,92 @@
+Broadcom Cygnus Pin Controller
+
+The Cygnus pin controller supports setting the alternate functions of groups
+of pins. Pinmux configuration on individual pins is not supported by the
+Cygnus A0 SoC.
+
+Required properties:
+
+- compatible:
+ Must be "brcm,cygnus-pinctrl"
+
+- reg:
+ Define the base and range of the I/O address space that contain the Cygnus
+pin control registers
+
+- brcm,groups:
+ This can be strings of one or more group names. This defines the group(s)
+that one wants to configure
+
+- brcm,function:
+ This is the alternate function that one wants to configure to. Valid
+alternate functions are "alt1", "alt2", "alt3", "alt4"
+
+Each child node represents a configuration. Client devices reference the the
+child node to enable the mux configuration.
+
+For example:
+
+ pinctrl: pinctrl@0x0301d0c8 {
+ compatible = "brcm,cygnus-pinctrl";
+ reg = <0x0301d0c8 0x2c>;
+
+ i2s_0: i2s_0 {
+ brcm,groups = "smart_card0", "smart_card0_fcb";
+ brcm,function = "alt2";
+ };
+
+ i2s_1: i2s_1 {
+ brcm,groups = "smart_card1", "smart_card1_fcb";
+ brcm,function = "alt2";
+ };
+
+ spi_0: spi_0 {
+ brcm,groups = "spi0";
+ brcm,function = "alt1";
+ };
+ }
+
+ spi0@18028000 {
+ compatible = "arm,pl022", "arm,primecell";
+ reg = <0x18028000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-0 = <&spi_0>;
+ clocks = <&axi81_clk>;
+ clock-names = "apb_pclk";
+ };
+
+Consider the following snapshot of Cygnus pinmux table:
+
+number pin group alt1 alt2 alt3 alt4
+------ --- ---- ---- ---- ---- ----
+42 sc0_clk smart_card0 SMART CARD0 I2S_0 N/A chip_gpio24
+43 sc0_cmdvcc_l smart_card0 SMART CARD0 I2S_0 N/A STRAP
+44 sc0_detect smart_card0 SMART CARD0 I2S_0 N/A chip_gpio25
+45 sc0_fcb smart_card0_fcb SMART CARD0_FCB I2S_0 N/A chip_gpio26
+46 sc0_io smart_card0 SMART CARD0 I2S_0 N/A chip_gpio27
+47 sc0_rst_l smart_card0 SMART CARD0 SPDIF N/A STRAP
+
+Note due to limitation of the Cygnus hardware, pinmux configuration can only
+be group based. To enable I2S_0 function, one needs the following child node
+configuration:
+
+ i2s_0: i2s_0 {
+ brcm,groups = "smart_card0", "smart_card0_fcb";
+ brcm,function = "alt2";
+ };
+
+This tells the Cygnus pin controller to configure groups "smart_card0" and
+"smart_card0_fcb" to I2S_0. With this configuration, pins 42, 43, 44, 45, 46
+become I2C_0, and pin 47 becomes SPDIF
+
+Consider another example, that one wants to configure the above pins as GPIO:
+
+ gpio_24_27: gpio_24_27 {
+ brcm,groups = "smart_card0", "smart_card0_fcb";
+ brcm,function = "alt4";
+ };
+
+With the above configuration, pins 42, 44, 45, 46 become GPIO, and 43 and 47
+become reserved for STRAP
--
1.7.9.5

2014-12-04 21:54:33

by Ray Jui

[permalink] [raw]
Subject: [PATCH 2/4] pinctrl: cygnus: add initial pinctrl support

This adds the initial driver support for the Broadcom Cygnus pinctrl
controller. The Cygnus pinctrl controller supports group based
alternate function configuration

Signed-off-by: Ray Jui <[email protected]>
Reviewed-by: Scott Branden <[email protected]>
Signed-off-by: Fengguang Wu <[email protected]>
---
drivers/pinctrl/Kconfig | 7 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/pinctrl-bcm-cygnus.c | 753 ++++++++++++++++++++++++++++++++++
3 files changed, 761 insertions(+)
create mode 100644 drivers/pinctrl/pinctrl-bcm-cygnus.c

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index d014f22..4549e9f 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -85,6 +85,13 @@ config PINCTRL_BCM281XX
BCM28145, and BCM28155 SoCs. This driver requires the pinctrl
framework. GPIO is provided by a separate GPIO driver.

+config PINCTRL_BCM_CYGNUS
+ bool "Broadcom Cygnus pinctrl driver"
+ depends on (ARCH_BCM_CYGNUS || COMPILE_TEST)
+ select PINMUX
+ select PINCONF
+ select GENERIC_PINCONF
+
config PINCTRL_LANTIQ
bool
depends on LANTIQ
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index c030b3d..4ed8e8a 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_PINCTRL_BF60x) += pinctrl-adi2-bf60x.o
obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o
obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o
obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o
+obj-$(CONFIG_PINCTRL_BCM_CYGNUS) += pinctrl-bcm-cygnus.o
obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o
obj-$(CONFIG_PINCTRL_PALMAS) += pinctrl-palmas.o
obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o
diff --git a/drivers/pinctrl/pinctrl-bcm-cygnus.c b/drivers/pinctrl/pinctrl-bcm-cygnus.c
new file mode 100644
index 0000000..eb6e27a
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-bcm-cygnus.c
@@ -0,0 +1,753 @@
+/*
+ * Copyright (C) 2014 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/slab.h>
+
+#include "core.h"
+#include "pinctrl-utils.h"
+
+/*
+ * Alternate function configuration
+ *
+ * @name: name of the alternate function
+ * @group_names: array of strings of group names that can be supported by this
+ * alternate function
+ * @num_groups: total number of groups that can be supported by this alternate
+ * function
+ * @mux: mux setting for this alternate function to be programed
+ */
+struct cygnus_pin_function {
+ const char *name;
+ const char * const *group_names;
+ const unsigned num_groups;
+ unsigned int mux;
+};
+
+/*
+ * Cygnus allows group based pinmux configuration
+ *
+ * @name: name of the group
+ * @pins: array of pins used by this group
+ * @num_pins: total number of pins used by this group
+ * @offset: register offset for pinmux configuration of this group
+ * @shift: bit shift for pinmux configuration of this group
+ */
+struct cygnus_pin_group {
+ const char *name;
+ const unsigned *pins;
+ const unsigned num_pins;
+ const unsigned int offset;
+ const unsigned int shift;
+};
+
+/*
+ * Cygnus pinctrl core
+ *
+ * @pctl: pointer to pinctrl_dev
+ * @dev: pointer to the device
+ * @base: I/O register base for Cygnus pinctrl configuration
+ *
+ */
+struct cygnus_pinctrl {
+ struct pinctrl_dev *pctl;
+ struct device *dev;
+ void __iomem *base;
+
+ const struct pinctrl_pin_desc *pins;
+ unsigned num_pins;
+
+ const struct cygnus_pin_group *groups;
+ unsigned num_groups;
+
+ const struct cygnus_pin_function *functions;
+ unsigned num_functions;
+};
+
+#define CYGNUS_PIN_GROUP(group_name, off, sh) \
+{ \
+ .name = #group_name, \
+ .pins = group_name##_pins, \
+ .num_pins = ARRAY_SIZE(group_name##_pins), \
+ .offset = off, \
+ .shift = sh, \
+}
+
+/*
+ * The following pin description is based on Cygnus I/O MUX spreadsheet
+ */
+static const struct pinctrl_pin_desc cygnus_pinctrl_pins[] = {
+ PINCTRL_PIN(0, "ext_device_reset_n"),
+ PINCTRL_PIN(1, "chip_mode0"),
+ PINCTRL_PIN(2, "chip_mode1"),
+ PINCTRL_PIN(3, "chip_mode2"),
+ PINCTRL_PIN(4, "chip_mode3"),
+ PINCTRL_PIN(5, "chip_mode4"),
+ PINCTRL_PIN(6, "bsc0_scl"),
+ PINCTRL_PIN(7, "bsc0_sda"),
+ PINCTRL_PIN(8, "bsc1_scl"),
+ PINCTRL_PIN(9, "bsc1_sda"),
+ PINCTRL_PIN(10, "d1w_dq"),
+ PINCTRL_PIN(11, "d1wowstz_l"),
+ PINCTRL_PIN(12, "gpio0"),
+ PINCTRL_PIN(13, "gpio1"),
+ PINCTRL_PIN(14, "gpio2"),
+ PINCTRL_PIN(15, "gpio3"),
+ PINCTRL_PIN(16, "gpio4"),
+ PINCTRL_PIN(17, "gpio5"),
+ PINCTRL_PIN(18, "gpio6"),
+ PINCTRL_PIN(19, "gpio7"),
+ PINCTRL_PIN(20, "gpio8"),
+ PINCTRL_PIN(21, "gpio9"),
+ PINCTRL_PIN(22, "gpio10"),
+ PINCTRL_PIN(23, "gpio11"),
+ PINCTRL_PIN(24, "gpio12"),
+ PINCTRL_PIN(25, "gpio13"),
+ PINCTRL_PIN(26, "gpio14"),
+ PINCTRL_PIN(27, "gpio15"),
+ PINCTRL_PIN(28, "gpio16"),
+ PINCTRL_PIN(29, "gpio17"),
+ PINCTRL_PIN(30, "gpio18"),
+ PINCTRL_PIN(31, "gpio19"),
+ PINCTRL_PIN(32, "gpio20"),
+ PINCTRL_PIN(33, "gpio21"),
+ PINCTRL_PIN(34, "gpio22"),
+ PINCTRL_PIN(35, "gpio23"),
+ PINCTRL_PIN(36, "mdc"),
+ PINCTRL_PIN(37, "mdio"),
+ PINCTRL_PIN(38, "pwm0"),
+ PINCTRL_PIN(39, "pwm1"),
+ PINCTRL_PIN(40, "pwm2"),
+ PINCTRL_PIN(41, "pwm3"),
+ PINCTRL_PIN(42, "sc0_clk"),
+ PINCTRL_PIN(43, "sc0_cmdvcc_l"),
+ PINCTRL_PIN(44, "sc0_detect"),
+ PINCTRL_PIN(45, "sc0_fcb"),
+ PINCTRL_PIN(46, "sc0_io"),
+ PINCTRL_PIN(47, "sc0_rst_l"),
+ PINCTRL_PIN(48, "sc1_clk"),
+ PINCTRL_PIN(49, "sc1_cmdvcc_l"),
+ PINCTRL_PIN(50, "sc1_detect"),
+ PINCTRL_PIN(51, "sc1_fcb"),
+ PINCTRL_PIN(52, "sc1_io"),
+ PINCTRL_PIN(53, "sc1_rst_l"),
+ PINCTRL_PIN(54, "spi0_clk"),
+ PINCTRL_PIN(55, "spi0_mosi"),
+ PINCTRL_PIN(56, "spi0_miso"),
+ PINCTRL_PIN(57, "spi0_ss"),
+ PINCTRL_PIN(58, "spi1_clk"),
+ PINCTRL_PIN(59, "spi1_mosi"),
+ PINCTRL_PIN(60, "spi1_miso"),
+ PINCTRL_PIN(61, "spi1_ss"),
+ PINCTRL_PIN(62, "spi2_clk"),
+ PINCTRL_PIN(63, "spi2_mosi"),
+ PINCTRL_PIN(64, "spi2_miso"),
+ PINCTRL_PIN(65, "spi2_ss"),
+ PINCTRL_PIN(66, "spi3_clk"),
+ PINCTRL_PIN(67, "spi3_mosi"),
+ PINCTRL_PIN(68, "spi3_miso"),
+ PINCTRL_PIN(69, "spi3_ss"),
+ PINCTRL_PIN(70, "uart0_cts"),
+ PINCTRL_PIN(71, "uart0_rts"),
+ PINCTRL_PIN(72, "uart0_rx"),
+ PINCTRL_PIN(73, "uart0_tx"),
+ PINCTRL_PIN(74, "uart1_cts"),
+ PINCTRL_PIN(75, "uart1_dcd"),
+ PINCTRL_PIN(76, "uart1_dsr"),
+ PINCTRL_PIN(77, "uart1_dtr"),
+ PINCTRL_PIN(78, "uart1_ri"),
+ PINCTRL_PIN(79, "uart1_rts"),
+ PINCTRL_PIN(80, "uart1_rx"),
+ PINCTRL_PIN(81, "uart1_tx"),
+ PINCTRL_PIN(82, "uart3_rx"),
+ PINCTRL_PIN(83, "uart3_tx"),
+ PINCTRL_PIN(84, "sdio1_clk_sdcard"),
+ PINCTRL_PIN(85, "sdio1_cmd"),
+ PINCTRL_PIN(86, "sdio1_data0"),
+ PINCTRL_PIN(87, "sdio1_data1"),
+ PINCTRL_PIN(88, "sdio1_data2"),
+ PINCTRL_PIN(89, "sdio1_data3"),
+ PINCTRL_PIN(90, "sdio1_wp_n"),
+ PINCTRL_PIN(91, "sdio1_card_rst"),
+ PINCTRL_PIN(92, "sdio1_led_on"),
+ PINCTRL_PIN(93, "sdio1_cd"),
+ PINCTRL_PIN(94, "sdio0_clk_sdcard"),
+ PINCTRL_PIN(95, "sdio0_cmd"),
+ PINCTRL_PIN(96, "sdio0_data0"),
+ PINCTRL_PIN(97, "sdio0_data1"),
+ PINCTRL_PIN(98, "sdio0_data2"),
+ PINCTRL_PIN(99, "sdio0_data3"),
+ PINCTRL_PIN(100, "sdio0_wp_n"),
+ PINCTRL_PIN(101, "sdio0_card_rst"),
+ PINCTRL_PIN(102, "sdio0_led_on"),
+ PINCTRL_PIN(103, "sdio0_cd"),
+ PINCTRL_PIN(104, "sflash_clk"),
+ PINCTRL_PIN(105, "sflash_cs_l"),
+ PINCTRL_PIN(106, "sflash_mosi"),
+ PINCTRL_PIN(107, "sflash_miso"),
+ PINCTRL_PIN(108, "sflash_wp_n"),
+ PINCTRL_PIN(109, "sflash_hold_n"),
+ PINCTRL_PIN(110, "nand_ale"),
+ PINCTRL_PIN(111, "nand_ce0_l"),
+ PINCTRL_PIN(112, "nand_ce1_l"),
+ PINCTRL_PIN(113, "nand_cle"),
+ PINCTRL_PIN(114, "nand_dq0"),
+ PINCTRL_PIN(115, "nand_dq1"),
+ PINCTRL_PIN(116, "nand_dq2"),
+ PINCTRL_PIN(117, "nand_dq3"),
+ PINCTRL_PIN(118, "nand_dq4"),
+ PINCTRL_PIN(119, "nand_dq5"),
+ PINCTRL_PIN(120, "nand_dq6"),
+ PINCTRL_PIN(121, "nand_dq7"),
+ PINCTRL_PIN(122, "nand_rb_l"),
+ PINCTRL_PIN(123, "nand_re_l"),
+ PINCTRL_PIN(124, "nand_we_l"),
+ PINCTRL_PIN(125, "nand_wp_l"),
+ PINCTRL_PIN(126, "lcd_clac"),
+ PINCTRL_PIN(127, "lcd_clcp"),
+ PINCTRL_PIN(128, "lcd_cld0"),
+ PINCTRL_PIN(129, "lcd_cld1"),
+ PINCTRL_PIN(130, "lcd_cld10"),
+ PINCTRL_PIN(131, "lcd_cld11"),
+ PINCTRL_PIN(132, "lcd_cld12"),
+ PINCTRL_PIN(133, "lcd_cld13"),
+ PINCTRL_PIN(134, "lcd_cld14"),
+ PINCTRL_PIN(135, "lcd_cld15"),
+ PINCTRL_PIN(136, "lcd_cld16"),
+ PINCTRL_PIN(137, "lcd_cld17"),
+ PINCTRL_PIN(138, "lcd_cld18"),
+ PINCTRL_PIN(139, "lcd_cld19"),
+ PINCTRL_PIN(140, "lcd_cld2"),
+ PINCTRL_PIN(141, "lcd_cld20"),
+ PINCTRL_PIN(142, "lcd_cld21"),
+ PINCTRL_PIN(143, "lcd_cld22"),
+ PINCTRL_PIN(144, "lcd_cld23"),
+ PINCTRL_PIN(145, "lcd_cld3"),
+ PINCTRL_PIN(146, "lcd_cld4"),
+ PINCTRL_PIN(147, "lcd_cld5"),
+ PINCTRL_PIN(148, "lcd_cld6"),
+ PINCTRL_PIN(149, "lcd_cld7"),
+ PINCTRL_PIN(150, "lcd_cld8"),
+ PINCTRL_PIN(151, "lcd_cld9"),
+ PINCTRL_PIN(152, "lcd_clfp"),
+ PINCTRL_PIN(153, "lcd_clle"),
+ PINCTRL_PIN(154, "lcd_cllp"),
+ PINCTRL_PIN(155, "lcd_clpower"),
+ PINCTRL_PIN(156, "camera_vsync"),
+ PINCTRL_PIN(157, "camera_trigger"),
+ PINCTRL_PIN(158, "camera_strobe"),
+ PINCTRL_PIN(159, "camera_standby"),
+ PINCTRL_PIN(160, "camera_reset_n"),
+ PINCTRL_PIN(161, "camera_pixdata9"),
+ PINCTRL_PIN(162, "camera_pixdata8"),
+ PINCTRL_PIN(163, "camera_pixdata7"),
+ PINCTRL_PIN(164, "camera_pixdata6"),
+ PINCTRL_PIN(165, "camera_pixdata5"),
+ PINCTRL_PIN(166, "camera_pixdata4"),
+ PINCTRL_PIN(167, "camera_pixdata3"),
+ PINCTRL_PIN(168, "camera_pixdata2"),
+ PINCTRL_PIN(169, "camera_pixdata1"),
+ PINCTRL_PIN(170, "camera_pixdata0"),
+ PINCTRL_PIN(171, "camera_pixclk"),
+ PINCTRL_PIN(172, "camera_hsync"),
+ PINCTRL_PIN(173, "camera_pll_ref_clk"),
+ PINCTRL_PIN(174, "usb_id_indication"),
+ PINCTRL_PIN(175, "usb_vbus_indication"),
+ PINCTRL_PIN(176, "gpio0_3p3"),
+ PINCTRL_PIN(177, "gpio1_3p3"),
+ PINCTRL_PIN(178, "gpio2_3p3"),
+ PINCTRL_PIN(179, "gpio3_3p3"),
+};
+
+/*
+ * List of groups of pins
+ */
+static const unsigned gpio0_pins[] = { 12 };
+static const unsigned gpio1_pins[] = { 13 };
+static const unsigned gpio2_pins[] = { 14 };
+static const unsigned gpio3_pins[] = { 15 };
+static const unsigned gpio4_pins[] = { 16 };
+static const unsigned gpio5_pins[] = { 17 };
+static const unsigned gpio6_pins[] = { 18 };
+static const unsigned gpio7_pins[] = { 19 };
+static const unsigned gpio8_pins[] = { 20 };
+static const unsigned gpio9_pins[] = { 21 };
+static const unsigned gpio10_pins[] = { 22 };
+static const unsigned gpio11_pins[] = { 23 };
+static const unsigned gpio12_pins[] = { 24 };
+static const unsigned gpio13_pins[] = { 25 };
+static const unsigned gpio14_pins[] = { 26 };
+static const unsigned gpio15_pins[] = { 27 };
+static const unsigned gpio16_pins[] = { 28 };
+static const unsigned gpio17_pins[] = { 29 };
+static const unsigned gpio18_pins[] = { 30 };
+static const unsigned gpio19_pins[] = { 31 };
+static const unsigned gpio20_pins[] = { 32 };
+static const unsigned gpio21_pins[] = { 33 };
+static const unsigned gpio22_pins[] = { 34 };
+static const unsigned gpio23_pins[] = { 35 };
+static const unsigned pwm0_pins[] = { 38 };
+static const unsigned pwm1_pins[] = { 39 };
+static const unsigned pwm2_pins[] = { 40 };
+static const unsigned pwm3_pins[] = { 41 };
+static const unsigned sdio0_pins[] = { 94, 95, 96, 97, 98, 99 };
+static const unsigned smart_card0_pins[] = { 42, 43, 44, 46, 47 };
+static const unsigned smart_card1_pins[] = { 48, 49, 50, 52, 53 };
+static const unsigned spi0_pins[] = { 54, 55, 56, 57 };
+static const unsigned spi1_pins[] = { 58, 59, 60, 61 };
+static const unsigned spi2_pins[] = { 62, 63, 64, 65 };
+static const unsigned spi3_pins[] = { 66, 67, 68, 69 };
+static const unsigned d1w_pins[] = { 10, 11 };
+static const unsigned lcd_pins[] = { 126, 127, 128, 129, 130, 131, 132, 133,
+ 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147,
+ 148, 149, 150, 151, 152, 153, 154, 155 };
+static const unsigned uart0_pins[] = { 70, 71, 72, 73 };
+static const unsigned uart1_dte_pins[] = { 75, 76, 77, 78 };
+static const unsigned uart1_pins[] = { 74, 79, 80, 81 };
+static const unsigned uart3_pins[] = { 82, 83 };
+static const unsigned qspi_pins[] = { 104, 105, 106, 107 };
+static const unsigned nand_pins[] = { 110, 111, 112, 113, 114, 115, 116, 117,
+ 118, 119, 120, 121, 122, 123, 124, 125 };
+static const unsigned sdio0_cd_pins[] = { 103 };
+static const unsigned sdio0_mmc_pins[] = { 100, 101, 102 };
+static const unsigned can0_spi4_pins[] = { 86, 87 };
+static const unsigned can1_spi4_pins[] = { 88, 89 };
+static const unsigned sdio1_cd_pins[] = { 93 };
+static const unsigned sdio1_led_pins[] = { 84, 85 };
+static const unsigned sdio1_mmc_pins[] = { 90, 91, 92 };
+static const unsigned camera_led_pins[] = { 156, 157, 158, 159, 160 };
+static const unsigned camera_rgmii_pins[] = { 169, 170, 171, 169, 170, 171,
+ 172, 173 };
+static const unsigned camera_sram_rgmii_pins[] = { 161, 162, 163, 164, 165,
+ 166, 167, 168 };
+static const unsigned qspi_gpio_pins[] = { 108, 109 };
+static const unsigned smart_card0_fcb_pins[] = { 45 };
+static const unsigned smart_card1_fcb_pins[] = { 51 };
+static const unsigned gpio0_3p3_pins[] = { 176 };
+static const unsigned gpio1_3p3_pins[] = { 177 };
+static const unsigned gpio2_3p3_pins[] = { 178 };
+
+/*
+ * List of groups names. Need to match the order in cygnus_pin_groups
+ */
+static const char * const cygnus_pin_group_names[] = {
+ "gpio0",
+ "gpio1",
+ "gpio2",
+ "gpio3",
+ "gpio4",
+ "gpio5",
+ "gpio6",
+ "gpio7",
+ "gpio8",
+ "gpio9",
+ "gpio10",
+ "gpio11",
+ "gpio12",
+ "gpio13",
+ "gpio14",
+ "gpio15",
+ "gpio16",
+ "gpio17",
+ "gpio18",
+ "gpio19",
+ "gpio20",
+ "gpio21",
+ "gpio22",
+ "gpio23",
+ "pwm0",
+ "pwm1",
+ "pwm2",
+ "pwm3",
+ "sdio0",
+ "smart_card0",
+ "smart_card1",
+ "spi0",
+ "spi1",
+ "spi2",
+ "spi3",
+ "d1w",
+ "lcd",
+ "uart0",
+ "uart1_dte",
+ "uart1",
+ "uart3",
+ "qspi",
+ "nand",
+ "sdio0_cd",
+ "sdio0_mmc",
+ "can0_spi4",
+ "can1_spi4",
+ "sdio1_cd",
+ "sdio1_led",
+ "sdio1_mmc",
+ "camera_led",
+ "camera_rgmii",
+ "camera_sram_rgmii",
+ "qspi_gpio",
+ "smart_card0_fcb",
+ "smart_card1_fcb",
+ "gpio0_3p3",
+ "gpio1_3p3",
+ "gpio2_3p3",
+};
+
+/*
+ * List of groups. Need to match the order in cygnus_pin_group_names
+ */
+static const struct cygnus_pin_group cygnus_pin_groups[] = {
+ CYGNUS_PIN_GROUP(gpio0, 0x0, 0),
+ CYGNUS_PIN_GROUP(gpio1, 0x0, 4),
+ CYGNUS_PIN_GROUP(gpio2, 0x0, 8),
+ CYGNUS_PIN_GROUP(gpio3, 0x0, 12),
+ CYGNUS_PIN_GROUP(gpio4, 0x0, 16),
+ CYGNUS_PIN_GROUP(gpio5, 0x0, 20),
+ CYGNUS_PIN_GROUP(gpio6, 0x0, 24),
+ CYGNUS_PIN_GROUP(gpio7, 0x0, 28),
+ CYGNUS_PIN_GROUP(gpio8, 0x4, 0),
+ CYGNUS_PIN_GROUP(gpio9, 0x4, 4),
+ CYGNUS_PIN_GROUP(gpio10, 0x4, 8),
+ CYGNUS_PIN_GROUP(gpio11, 0x4, 12),
+ CYGNUS_PIN_GROUP(gpio12, 0x4, 16),
+ CYGNUS_PIN_GROUP(gpio13, 0x4, 20),
+ CYGNUS_PIN_GROUP(gpio14, 0x4, 24),
+ CYGNUS_PIN_GROUP(gpio15, 0x4, 28),
+ CYGNUS_PIN_GROUP(gpio16, 0x8, 0),
+ CYGNUS_PIN_GROUP(gpio17, 0x8, 4),
+ CYGNUS_PIN_GROUP(gpio18, 0x8, 8),
+ CYGNUS_PIN_GROUP(gpio19, 0x8, 12),
+ CYGNUS_PIN_GROUP(gpio20, 0x8, 16),
+ CYGNUS_PIN_GROUP(gpio21, 0x8, 20),
+ CYGNUS_PIN_GROUP(gpio22, 0x8, 24),
+ CYGNUS_PIN_GROUP(gpio23, 0x8, 28),
+ CYGNUS_PIN_GROUP(pwm0, 0xc, 0),
+ CYGNUS_PIN_GROUP(pwm1, 0xc, 4),
+ CYGNUS_PIN_GROUP(pwm2, 0xc, 8),
+ CYGNUS_PIN_GROUP(pwm3, 0xc, 12),
+ CYGNUS_PIN_GROUP(sdio0, 0xc, 16),
+ CYGNUS_PIN_GROUP(smart_card0, 0xc, 20),
+ CYGNUS_PIN_GROUP(smart_card1, 0xc, 24),
+ CYGNUS_PIN_GROUP(spi0, 0x10, 0),
+ CYGNUS_PIN_GROUP(spi1, 0x10, 4),
+ CYGNUS_PIN_GROUP(spi2, 0x10, 8),
+ CYGNUS_PIN_GROUP(spi3, 0x10, 12),
+ CYGNUS_PIN_GROUP(d1w, 0x10, 16),
+ CYGNUS_PIN_GROUP(lcd, 0x10, 20),
+ CYGNUS_PIN_GROUP(uart0, 0x14, 0),
+ CYGNUS_PIN_GROUP(uart1_dte, 0x14, 4),
+ CYGNUS_PIN_GROUP(uart1, 0x14, 8),
+ CYGNUS_PIN_GROUP(uart3, 0x14, 12),
+ CYGNUS_PIN_GROUP(qspi, 0x14, 16),
+ CYGNUS_PIN_GROUP(nand, 0x14, 20),
+ CYGNUS_PIN_GROUP(sdio0_cd, 0x18, 0),
+ CYGNUS_PIN_GROUP(sdio0_mmc, 0x18, 4),
+ CYGNUS_PIN_GROUP(can0_spi4, 0x18, 8),
+ CYGNUS_PIN_GROUP(can1_spi4, 0x18, 12),
+ CYGNUS_PIN_GROUP(sdio1_cd, 0x18, 16),
+ CYGNUS_PIN_GROUP(sdio1_led, 0x18, 20),
+ CYGNUS_PIN_GROUP(sdio1_mmc, 0x18, 24),
+ CYGNUS_PIN_GROUP(camera_led, 0x1c, 0),
+ CYGNUS_PIN_GROUP(camera_rgmii, 0x1c, 4),
+ CYGNUS_PIN_GROUP(camera_sram_rgmii, 0x1c, 8),
+ CYGNUS_PIN_GROUP(qspi_gpio, 0x1c, 12),
+ CYGNUS_PIN_GROUP(smart_card0_fcb, 0x20, 0),
+ CYGNUS_PIN_GROUP(smart_card1_fcb, 0x20, 4),
+ CYGNUS_PIN_GROUP(gpio0_3p3, 0x28, 0),
+ CYGNUS_PIN_GROUP(gpio1_3p3, 0x28, 4),
+ CYGNUS_PIN_GROUP(gpio2_3p3, 0x28, 8),
+};
+
+#define CYGNUS_PIN_FUNCTION(fcn_name, mux_val) \
+{ \
+ .name = #fcn_name, \
+ .group_names = cygnus_pin_group_names, \
+ .num_groups = ARRAY_SIZE(cygnus_pin_group_names), \
+ .mux = mux_val, \
+}
+
+/*
+ * Cygnus has 4 alternate functions. All groups can be configured to any of
+ * the 4 alternate functions
+ */
+static const struct cygnus_pin_function cygnus_pin_functions[] = {
+ CYGNUS_PIN_FUNCTION(alt1, 0),
+ CYGNUS_PIN_FUNCTION(alt2, 1),
+ CYGNUS_PIN_FUNCTION(alt3, 2),
+ CYGNUS_PIN_FUNCTION(alt4, 3),
+};
+
+static int cygnus_get_groups_count(struct pinctrl_dev *pctrl_dev)
+{
+ struct cygnus_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
+
+ return pinctrl->num_groups;
+}
+
+static const char *cygnus_get_group_name(struct pinctrl_dev *pctrl_dev,
+ unsigned selector)
+{
+ struct cygnus_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
+
+ return pinctrl->groups[selector].name;
+}
+
+static int cygnus_get_group_pins(struct pinctrl_dev *pctrl_dev,
+ unsigned selector, const unsigned **pins,
+ unsigned *num_pins)
+{
+ struct cygnus_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
+
+ *pins = pinctrl->groups[selector].pins;
+ *num_pins = pinctrl->groups[selector].num_pins;
+
+ return 0;
+}
+
+static void cygnus_pin_dbg_show(struct pinctrl_dev *pctrl_dev,
+ struct seq_file *s, unsigned offset)
+{
+ seq_printf(s, " %s", dev_name(pctrl_dev->dev));
+}
+
+static int find_matched_function(const char *function_name)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(cygnus_pin_functions); i++) {
+ if (!strcmp(cygnus_pin_functions[i].name, function_name))
+ return (int)cygnus_pin_functions[i].mux;
+ }
+
+ return -EINVAL;
+}
+
+static int cygnus_dt_node_to_map(struct pinctrl_dev *pctrl_dev,
+ struct device_node *np, struct pinctrl_map **map,
+ unsigned *num_maps)
+{
+ int ret, num_groups;
+ unsigned reserved_maps = 0;
+ struct property *prop;
+ const char *group_name, *function_name;
+
+ *map = NULL;
+ *num_maps = 0;
+
+ num_groups = of_property_count_strings(np, "brcm,groups");
+ if (num_groups < 0) {
+ dev_err(pctrl_dev->dev,
+ "could not parse property brcm,groups\n");
+ return -EINVAL;
+ }
+
+ ret = of_property_read_string(np, "brcm,function", &function_name);
+ if (ret < 0) {
+ dev_err(pctrl_dev->dev,
+ "could not parse property brcm,function\n");
+ return -EINVAL;
+ }
+
+ /* make sure it's a valid alternate function */
+ ret = find_matched_function(function_name);
+ if (ret < 0) {
+ dev_err(pctrl_dev->dev, "invalid function name: %s\n",
+ function_name);
+ }
+
+ ret = pinctrl_utils_reserve_map(pctrl_dev, map, &reserved_maps,
+ num_maps, num_groups);
+ if (ret) {
+ dev_err(pctrl_dev->dev, "unable to reserve map\n");
+ return ret;
+ }
+
+ of_property_for_each_string(np, "brcm,groups", prop, group_name) {
+ ret = pinctrl_utils_add_map_mux(pctrl_dev, map,
+ &reserved_maps, num_maps, group_name,
+ function_name);
+ if (ret) {
+ dev_err(pctrl_dev->dev, "can't add map: %d\n", ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static struct pinctrl_ops cygnus_pinctrl_ops = {
+ .get_groups_count = cygnus_get_groups_count,
+ .get_group_name = cygnus_get_group_name,
+ .get_group_pins = cygnus_get_group_pins,
+ .pin_dbg_show = cygnus_pin_dbg_show,
+ .dt_node_to_map = cygnus_dt_node_to_map,
+ .dt_free_map = pinctrl_utils_dt_free_map,
+};
+
+static int cygnus_get_functions_count(struct pinctrl_dev *pctrl_dev)
+{
+ struct cygnus_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
+
+ return pinctrl->num_functions;
+}
+
+static const char *cygnus_get_function_name(struct pinctrl_dev *pctrl_dev,
+ unsigned selector)
+{
+ struct cygnus_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
+
+ return pinctrl->functions[selector].name;
+}
+
+static int cygnus_get_function_groups(struct pinctrl_dev *pctrl_dev,
+ unsigned selector, const char * const **groups,
+ unsigned * const num_groups)
+{
+ struct cygnus_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
+
+ *groups = pinctrl->functions[selector].group_names;
+ *num_groups = pinctrl->functions[selector].num_groups;
+
+ return 0;
+}
+
+static int cygnus_pinmux_set_mux(struct pinctrl_dev *pctrl_dev,
+ unsigned function_selector, unsigned group_selector)
+{
+ struct cygnus_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
+ const struct cygnus_pin_function *function =
+ &pinctrl->functions[function_selector];
+ const struct cygnus_pin_group *group =
+ &pinctrl->groups[group_selector];
+ u32 val, mask = 0x7;
+
+ dev_dbg(pctrl_dev->dev,
+ "group:%s with offset:0x%08x shift:%u set to function: %s mux:%u\n",
+ group->name, group->offset, group->shift, function->name,
+ function->mux);
+
+ val = readl(pinctrl->base + group->offset);
+ val &= ~(mask << group->shift);
+ val |= function->mux << group->shift;
+ writel(val, pinctrl->base + group->offset);
+
+ return 0;
+}
+
+static struct pinmux_ops cygnus_pinmux_ops = {
+ .get_functions_count = cygnus_get_functions_count,
+ .get_function_name = cygnus_get_function_name,
+ .get_function_groups = cygnus_get_function_groups,
+ .set_mux = cygnus_pinmux_set_mux,
+};
+
+static struct pinctrl_desc cygnus_pinctrl_desc = {
+ .pctlops = &cygnus_pinctrl_ops,
+ .pmxops = &cygnus_pinmux_ops,
+ .owner = THIS_MODULE,
+};
+
+static int cygnus_pinctrl_probe(struct platform_device *pdev)
+{
+ struct cygnus_pinctrl *pinctrl;
+ struct resource *res;
+
+ pinctrl = devm_kzalloc(&pdev->dev, sizeof(*pinctrl), GFP_KERNEL);
+ if (!pinctrl) {
+ dev_err(&pdev->dev, "unable to allocate memory\n");
+ return -ENOMEM;
+ }
+ pinctrl->dev = &pdev->dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "unable to get resource\n");
+ return -ENOENT;
+ }
+
+ pinctrl->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(pinctrl->base)) {
+ dev_err(&pdev->dev, "unable to map I/O space\n");
+ return PTR_ERR(pinctrl->base);
+ }
+
+ pinctrl->pins = cygnus_pinctrl_pins;
+ pinctrl->num_pins = ARRAY_SIZE(cygnus_pinctrl_pins);
+ pinctrl->groups = cygnus_pin_groups;
+ pinctrl->num_groups = ARRAY_SIZE(cygnus_pin_groups);
+ pinctrl->functions = cygnus_pin_functions;
+ pinctrl->num_functions = ARRAY_SIZE(cygnus_pin_functions);
+
+ cygnus_pinctrl_desc.name = dev_name(&pdev->dev);
+ cygnus_pinctrl_desc.pins = cygnus_pinctrl_pins;
+ cygnus_pinctrl_desc.npins = ARRAY_SIZE(cygnus_pinctrl_pins);
+
+ pinctrl->pctl = pinctrl_register(&cygnus_pinctrl_desc, &pdev->dev,
+ pinctrl);
+ if (!pinctrl->pctl) {
+ dev_err(&pdev->dev, "unable to register cygnus pinctrl\n");
+ return -EINVAL;
+ }
+
+ platform_set_drvdata(pdev, pinctrl);
+
+ return 0;
+}
+
+static int cygnus_pinctrl_remove(struct platform_device *pdev)
+{
+ struct cygnus_pinctrl *pinctrl = platform_get_drvdata(pdev);
+
+ pinctrl_unregister(pinctrl->pctl);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static struct of_device_id cygnus_pinctrl_of_match[] = {
+ { .compatible = "brcm,cygnus-pinctrl", },
+ { },
+};
+
+static struct platform_driver cygnus_pinctrl_driver = {
+ .driver = {
+ .name = "cygnus-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = cygnus_pinctrl_of_match,
+ },
+ .probe = cygnus_pinctrl_probe,
+ .remove = cygnus_pinctrl_remove,
+};
+
+static int __init cygnus_pinctrl_init(void)
+{
+ return platform_driver_register(&cygnus_pinctrl_driver);
+}
+arch_initcall(cygnus_pinctrl_init);
+
+static void __exit cygnus_pinctrl_exit(void)
+{
+ platform_driver_unregister(&cygnus_pinctrl_driver);
+}
+module_exit(cygnus_pinctrl_exit);
+
+MODULE_AUTHOR("Ray Jui <[email protected]>");
+MODULE_DESCRIPTION("Broadcom Cygnus pinctrl driver");
+MODULE_LICENSE("GPL v2");
--
1.7.9.5

2014-12-04 21:54:39

by Ray Jui

[permalink] [raw]
Subject: [PATCH 3/4] ARM: mach-bcm: enable pinctrl support for Cygnus

This enables the pinctrl driver for Broadcom Cygnus SoC

Signed-off-by: Ray Jui <[email protected]>
---
arch/arm/mach-bcm/Kconfig | 1 +
1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
index aaeec78..b4efff2 100644
--- a/arch/arm/mach-bcm/Kconfig
+++ b/arch/arm/mach-bcm/Kconfig
@@ -29,6 +29,7 @@ config ARCH_BCM_IPROC
config ARCH_BCM_CYGNUS
bool "Broadcom Cygnus Support" if ARCH_MULTI_V7
select ARCH_BCM_IPROC
+ select PINCTRL_BCM_CYGNUS
help
Enable support for the Cygnus family,
which includes the following variants:
--
1.7.9.5

2014-12-04 21:54:55

by Ray Jui

[permalink] [raw]
Subject: [PATCH 4/4] ARM: dts: enable pinctrl for Broadcom Cygnus

This enables the pinctrl support for Broadcom Cygnus SoC

Signed-off-by: Ray Jui <[email protected]>
---
arch/arm/boot/dts/bcm-cygnus.dtsi | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/bcm-cygnus.dtsi b/arch/arm/boot/dts/bcm-cygnus.dtsi
index 5126f9e..4c6bf4d 100644
--- a/arch/arm/boot/dts/bcm-cygnus.dtsi
+++ b/arch/arm/boot/dts/bcm-cygnus.dtsi
@@ -54,6 +54,11 @@

/include/ "bcm-cygnus-clock.dtsi"

+ pinctrl: pinctrl@0x0301d0c8 {
+ compatible = "brcm,cygnus-pinctrl";
+ reg = <0x0301d0c8 0x2c>;
+ };
+
amba {
#address-cells = <1>;
#size-cells = <1>;
--
1.7.9.5

2014-12-04 22:16:34

by Belisko Marek

[permalink] [raw]
Subject: Re: [PATCH 1/4] pinctrl: Broadcom Cygnus pinctrl device tree binding

On Thu, Dec 4, 2014 at 10:56 PM, Ray Jui <[email protected]> wrote:
> Device tree binding documentation for Broadcom Cygnus pinctrl driver
>
> Signed-off-by: Ray Jui <[email protected]>
> Reviewed-by: Scott Branden <[email protected]>
> ---
> .../bindings/pinctrl/brcm,cygnus-pinctrl.txt | 92 ++++++++++++++++++++
> 1 file changed, 92 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinctrl.txt
>
> diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinctrl.txt
> new file mode 100644
> index 0000000..86e4579
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinctrl.txt
> @@ -0,0 +1,92 @@
> +Broadcom Cygnus Pin Controller
> +
> +The Cygnus pin controller supports setting the alternate functions of groups
> +of pins. Pinmux configuration on individual pins is not supported by the
> +Cygnus A0 SoC.
> +
> +Required properties:
> +
> +- compatible:
> + Must be "brcm,cygnus-pinctrl"
> +
> +- reg:
> + Define the base and range of the I/O address space that contain the Cygnus
> +pin control registers
> +
> +- brcm,groups:
> + This can be strings of one or more group names. This defines the group(s)
> +that one wants to configure
> +
> +- brcm,function:
> + This is the alternate function that one wants to configure to. Valid
> +alternate functions are "alt1", "alt2", "alt3", "alt4"
> +
> +Each child node represents a configuration. Client devices reference the the
> +child node to enable the mux configuration.
> +
> +For example:
> +
> + pinctrl: pinctrl@0x0301d0c8 {
> + compatible = "brcm,cygnus-pinctrl";
> + reg = <0x0301d0c8 0x2c>;
> +
> + i2s_0: i2s_0 {
> + brcm,groups = "smart_card0", "smart_card0_fcb";
> + brcm,function = "alt2";
> + };
> +
> + i2s_1: i2s_1 {
> + brcm,groups = "smart_card1", "smart_card1_fcb";
> + brcm,function = "alt2";
> + };
> +
> + spi_0: spi_0 {
> + brcm,groups = "spi0";
> + brcm,function = "alt1";
> + };
> + }
> +
> + spi0@18028000 {
> + compatible = "arm,pl022", "arm,primecell";
> + reg = <0x18028000 0x1000>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
> + pinctrl-0 = <&spi_0>;
> + clocks = <&axi81_clk>;
> + clock-names = "apb_pclk";
> + };
> +
> +Consider the following snapshot of Cygnus pinmux table:
> +
> +number pin group alt1 alt2 alt3 alt4
> +------ --- ---- ---- ---- ---- ----
> +42 sc0_clk smart_card0 SMART CARD0 I2S_0 N/A chip_gpio24
> +43 sc0_cmdvcc_l smart_card0 SMART CARD0 I2S_0 N/A STRAP
> +44 sc0_detect smart_card0 SMART CARD0 I2S_0 N/A chip_gpio25
> +45 sc0_fcb smart_card0_fcb SMART CARD0_FCB I2S_0 N/A chip_gpio26
> +46 sc0_io smart_card0 SMART CARD0 I2S_0 N/A chip_gpio27
> +47 sc0_rst_l smart_card0 SMART CARD0 SPDIF N/A STRAP
> +
> +Note due to limitation of the Cygnus hardware, pinmux configuration can only
> +be group based. To enable I2S_0 function, one needs the following child node
> +configuration:
> +
> + i2s_0: i2s_0 {
> + brcm,groups = "smart_card0", "smart_card0_fcb";
> + brcm,function = "alt2";
> + };
> +
> +This tells the Cygnus pin controller to configure groups "smart_card0" and
> +"smart_card0_fcb" to I2S_0. With this configuration, pins 42, 43, 44, 45, 46
> +become I2C_0, and pin 47 becomes SPDIF
^^^^ typo - should be I2S_0
> +
> +Consider another example, that one wants to configure the above pins as GPIO:
> +
> + gpio_24_27: gpio_24_27 {
> + brcm,groups = "smart_card0", "smart_card0_fcb";
> + brcm,function = "alt4";
> + };
> +
> +With the above configuration, pins 42, 44, 45, 46 become GPIO, and 43 and 47
> +become reserved for STRAP
> --
> 1.7.9.5
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

BR,

marek

--
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
twitter: #opennandra
web: http://open-nandra.com

2014-12-04 22:35:29

by Ray Jui

[permalink] [raw]
Subject: Re: [PATCH 1/4] pinctrl: Broadcom Cygnus pinctrl device tree binding



On 12/4/2014 2:16 PM, Belisko Marek wrote:
> On Thu, Dec 4, 2014 at 10:56 PM, Ray Jui <[email protected]> wrote:
>> Device tree binding documentation for Broadcom Cygnus pinctrl driver
>>
>> Signed-off-by: Ray Jui <[email protected]>
>> Reviewed-by: Scott Branden <[email protected]>
>> ---
>> .../bindings/pinctrl/brcm,cygnus-pinctrl.txt | 92 ++++++++++++++++++++
>> 1 file changed, 92 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinctrl.txt
>>
>> diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinctrl.txt
>> new file mode 100644
>> index 0000000..86e4579
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/pinctrl/brcm,cygnus-pinctrl.txt
>> @@ -0,0 +1,92 @@
>> +Broadcom Cygnus Pin Controller
>> +
>> +The Cygnus pin controller supports setting the alternate functions of groups
>> +of pins. Pinmux configuration on individual pins is not supported by the
>> +Cygnus A0 SoC.
>> +
>> +Required properties:
>> +
>> +- compatible:
>> + Must be "brcm,cygnus-pinctrl"
>> +
>> +- reg:
>> + Define the base and range of the I/O address space that contain the Cygnus
>> +pin control registers
>> +
>> +- brcm,groups:
>> + This can be strings of one or more group names. This defines the group(s)
>> +that one wants to configure
>> +
>> +- brcm,function:
>> + This is the alternate function that one wants to configure to. Valid
>> +alternate functions are "alt1", "alt2", "alt3", "alt4"
>> +
>> +Each child node represents a configuration. Client devices reference the the
>> +child node to enable the mux configuration.
>> +
>> +For example:
>> +
>> + pinctrl: pinctrl@0x0301d0c8 {
>> + compatible = "brcm,cygnus-pinctrl";
>> + reg = <0x0301d0c8 0x2c>;
>> +
>> + i2s_0: i2s_0 {
>> + brcm,groups = "smart_card0", "smart_card0_fcb";
>> + brcm,function = "alt2";
>> + };
>> +
>> + i2s_1: i2s_1 {
>> + brcm,groups = "smart_card1", "smart_card1_fcb";
>> + brcm,function = "alt2";
>> + };
>> +
>> + spi_0: spi_0 {
>> + brcm,groups = "spi0";
>> + brcm,function = "alt1";
>> + };
>> + }
>> +
>> + spi0@18028000 {
>> + compatible = "arm,pl022", "arm,primecell";
>> + reg = <0x18028000 0x1000>;
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> + interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
>> + pinctrl-0 = <&spi_0>;
>> + clocks = <&axi81_clk>;
>> + clock-names = "apb_pclk";
>> + };
>> +
>> +Consider the following snapshot of Cygnus pinmux table:
>> +
>> +number pin group alt1 alt2 alt3 alt4
>> +------ --- ---- ---- ---- ---- ----
>> +42 sc0_clk smart_card0 SMART CARD0 I2S_0 N/A chip_gpio24
>> +43 sc0_cmdvcc_l smart_card0 SMART CARD0 I2S_0 N/A STRAP
>> +44 sc0_detect smart_card0 SMART CARD0 I2S_0 N/A chip_gpio25
>> +45 sc0_fcb smart_card0_fcb SMART CARD0_FCB I2S_0 N/A chip_gpio26
>> +46 sc0_io smart_card0 SMART CARD0 I2S_0 N/A chip_gpio27
>> +47 sc0_rst_l smart_card0 SMART CARD0 SPDIF N/A STRAP
>> +
>> +Note due to limitation of the Cygnus hardware, pinmux configuration can only
>> +be group based. To enable I2S_0 function, one needs the following child node
>> +configuration:
>> +
>> + i2s_0: i2s_0 {
>> + brcm,groups = "smart_card0", "smart_card0_fcb";
>> + brcm,function = "alt2";
>> + };
>> +
>> +This tells the Cygnus pin controller to configure groups "smart_card0" and
>> +"smart_card0_fcb" to I2S_0. With this configuration, pins 42, 43, 44, 45, 46
>> +become I2C_0, and pin 47 becomes SPDIF
> ^^^^ typo - should be I2S_0
Oh yeah. Will change from I2C_0 to I2S_0. Thanks.
>> +
>> +Consider another example, that one wants to configure the above pins as GPIO:
>> +
>> + gpio_24_27: gpio_24_27 {
>> + brcm,groups = "smart_card0", "smart_card0_fcb";
>> + brcm,function = "alt4";
>> + };
>> +
>> +With the above configuration, pins 42, 44, 45, 46 become GPIO, and 43 and 47
>> +become reserved for STRAP
>> --
>> 1.7.9.5
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> [email protected]
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
> BR,
>
> marek
>