sh-pfc: Support pins not associated with a GPIO port
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Mon, 15 Jul 2013 19:10:54 +0000 (21:10 +0200)
committerLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Mon, 29 Jul 2013 13:17:49 +0000 (15:17 +0200)
Pins with selectable functions but without a GPIO port can't be named
PORT_# or GP_#_#. Add a SH_PFC_PIN_NAMED macro to declare such pins in
the pinmux pins array, naming them with the PIN_ prefix followed by the
pin physical position.

In order to make sure not to register those pins as GPIOs, add a
SH_PFC_PIN_CFG_NO_GPIO pin flag to denote pins without a GPIO port.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Tested-by: Yusuke Goda <yusuke.goda.sx@renesas.com>
drivers/pinctrl/sh-pfc/core.c
drivers/pinctrl/sh-pfc/gpio.c
drivers/pinctrl/sh-pfc/pfc-r8a7778.c
drivers/pinctrl/sh-pfc/pfc-sh73a0.c
drivers/pinctrl/sh-pfc/sh_pfc.h

index cb47bce..9e66614 100644 (file)
@@ -362,7 +362,10 @@ static int sh_pfc_init_ranges(struct sh_pfc *pfc)
                return 0;
        }
 
-       /* Count, allocate and fill the ranges. */
+       /* Count, allocate and fill the ranges. The PFC SoC data pins array must
+        * be sorted by pin numbers, and pins without a GPIO port must come
+        * last.
+        */
        for (i = 1, nr_ranges = 1; i < pfc->info->nr_pins; ++i) {
                if (pfc->info->pins[i-1].pin != pfc->info->pins[i].pin - 1)
                        nr_ranges++;
@@ -378,15 +381,20 @@ static int sh_pfc_init_ranges(struct sh_pfc *pfc)
        range->start = pfc->info->pins[0].pin;
 
        for (i = 1; i < pfc->info->nr_pins; ++i) {
-               if (pfc->info->pins[i-1].pin != pfc->info->pins[i].pin - 1) {
-                       range->end = pfc->info->pins[i-1].pin;
-                       range++;
-                       range->start = pfc->info->pins[i].pin;
-               }
+               if (pfc->info->pins[i-1].pin == pfc->info->pins[i].pin - 1)
+                       continue;
+
+               range->end = pfc->info->pins[i-1].pin;
+               if (!(pfc->info->pins[i-1].configs & SH_PFC_PIN_CFG_NO_GPIO))
+                       pfc->nr_gpio_pins = range->end + 1;
+
+               range++;
+               range->start = pfc->info->pins[i].pin;
        }
 
        range->end = pfc->info->pins[i-1].pin;
-       pfc->nr_gpio_pins = range->end + 1;
+       if (!(pfc->info->pins[i-1].configs & SH_PFC_PIN_CFG_NO_GPIO))
+               pfc->nr_gpio_pins = range->end + 1;
 
        return 0;
 }
index 78fcb80..04bf52b 100644 (file)
@@ -364,10 +364,16 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
 
        pfc->gpio = chip;
 
-       /* Register the GPIO to pin mappings. */
+       /* Register the GPIO to pin mappings. As pins with GPIO ports must come
+        * first in the ranges, skip the pins without GPIO ports by stopping at
+        * the first range that contains such a pin.
+        */
        for (i = 0; i < pfc->nr_ranges; ++i) {
                const struct sh_pfc_pin_range *range = &pfc->ranges[i];
 
+               if (range->start >= pfc->nr_gpio_pins)
+                       break;
+
                ret = gpiochip_add_pin_range(&chip->gpio_chip,
                                             dev_name(pfc->dev),
                                             range->start, range->start,
index 40aecfe..428d2a6 100644 (file)
@@ -1254,16 +1254,21 @@ static const u16 pinmux_data[] = {
        PINMUX_IPSR_MSEL(IP10_24_22,    CAN_CLK_C,      SEL_CANCLK_C),
 };
 
-static struct sh_pfc_pin pinmux_pins[] = {
-       PINMUX_GPIO_GP_ALL(),
-};
-
 /* Pin numbers for pins without a corresponding GPIO port number are computed
  * from the row and column numbers with a 1000 offset to avoid collisions with
  * GPIO port numbers.
  */
 #define PIN_NUMBER(row, col)           (1000+((row)-1)*25+(col)-1)
 
+static struct sh_pfc_pin pinmux_pins[] = {
+       PINMUX_GPIO_GP_ALL(),
+
+       /* Pins not associated with a GPIO port */
+       SH_PFC_PIN_NAMED(3, 20, C20),
+       SH_PFC_PIN_NAMED(20, 1, T1),
+       SH_PFC_PIN_NAMED(25, 2, Y2),
+};
+
 /* - macro */
 #define SH_PFC_PINS(name, args...) \
        static const unsigned int name ##_pins[] = { args }
index 1f4dbe4..6417be5 100644 (file)
@@ -1173,6 +1173,12 @@ static const u16 pinmux_data[] = {
 #define SH73A0_PIN_IO_PU_PD(pin)       SH_PFC_PIN_CFG(pin, __IO | __PUD)
 #define SH73A0_PIN_O(pin)              SH_PFC_PIN_CFG(pin, __O)
 
+/* Pin numbers for pins without a corresponding GPIO port number are computed
+ * from the row and column numbers with a 1000 offset to avoid collisions with
+ * GPIO port numbers.
+ */
+#define PIN_NUMBER(row, col)           (1000+((row)-1)*34+(col)-1)
+
 static struct sh_pfc_pin pinmux_pins[] = {
        /* Table 25-1 (I/O and Pull U/D) */
        SH73A0_PIN_I_PD(0),
@@ -1444,13 +1450,10 @@ static struct sh_pfc_pin pinmux_pins[] = {
        SH73A0_PIN_O(307),
        SH73A0_PIN_I_PU(308),
        SH73A0_PIN_O(309),
-};
 
-/* Pin numbers for pins without a corresponding GPIO port number are computed
- * from the row and column numbers with a 1000 offset to avoid collisions with
- * GPIO port numbers.
- */
-#define PIN_NUMBER(row, col)           (1000+((row)-1)*34+(col)-1)
+       /* Pins not associated with a GPIO port */
+       SH_PFC_PIN_NAMED(6, 26, F26),
+};
 
 /* - BSC -------------------------------------------------------------------- */
 static const unsigned int bsc_data_0_7_pins[] = {
index 2469b35..11bd0d9 100644 (file)
@@ -26,6 +26,7 @@ enum {
 #define SH_PFC_PIN_CFG_OUTPUT          (1 << 1)
 #define SH_PFC_PIN_CFG_PULL_UP         (1 << 2)
 #define SH_PFC_PIN_CFG_PULL_DOWN       (1 << 3)
+#define SH_PFC_PIN_CFG_NO_GPIO         (1 << 31)
 
 struct sh_pfc_pin {
        u16 pin;
@@ -266,6 +267,14 @@ struct sh_pfc_soc_info {
                .configs = cfgs,                                        \
        }
 
+/* SH_PFC_PIN_NAMED - Expand to a sh_pfc_pin entry with the given name */
+#define SH_PFC_PIN_NAMED(row, col, _name)                              \
+       {                                                               \
+               .pin = PIN_NUMBER(row, col),                            \
+               .name = __stringify(PIN_##_name),                       \
+               .configs = SH_PFC_PIN_CFG_NO_GPIO,                      \
+       }
+
 /* PINMUX_DATA_ALL - Expand to a list of PORT_name_DATA, PORT_name_FN0,
  *                  PORT_name_OUT, PORT_name_IN marks
  */