linux/drivers/pinctrl/pinctrl-ingenic.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Ingenic SoCs pinctrl driver
   4 *
   5 * Copyright (c) 2017 Paul Cercueil <paul@crapouillou.net>
   6 */
   7
   8#include <linux/compiler.h>
   9#include <linux/gpio/driver.h>
  10#include <linux/interrupt.h>
  11#include <linux/io.h>
  12#include <linux/of_device.h>
  13#include <linux/of_irq.h>
  14#include <linux/of_platform.h>
  15#include <linux/pinctrl/pinctrl.h>
  16#include <linux/pinctrl/pinmux.h>
  17#include <linux/pinctrl/pinconf.h>
  18#include <linux/pinctrl/pinconf-generic.h>
  19#include <linux/platform_device.h>
  20#include <linux/regmap.h>
  21#include <linux/slab.h>
  22
  23#include "core.h"
  24#include "pinconf.h"
  25#include "pinmux.h"
  26
  27#define GPIO_PIN        0x00
  28#define GPIO_MSK        0x20
  29
  30#define JZ4740_GPIO_DATA        0x10
  31#define JZ4740_GPIO_PULL_DIS    0x30
  32#define JZ4740_GPIO_FUNC        0x40
  33#define JZ4740_GPIO_SELECT      0x50
  34#define JZ4740_GPIO_DIR         0x60
  35#define JZ4740_GPIO_TRIG        0x70
  36#define JZ4740_GPIO_FLAG        0x80
  37
  38#define JZ4770_GPIO_INT         0x10
  39#define JZ4770_GPIO_PAT1        0x30
  40#define JZ4770_GPIO_PAT0        0x40
  41#define JZ4770_GPIO_FLAG        0x50
  42#define JZ4770_GPIO_PEN         0x70
  43
  44#define REG_SET(x) ((x) + 0x4)
  45#define REG_CLEAR(x) ((x) + 0x8)
  46
  47#define PINS_PER_GPIO_CHIP 32
  48
  49enum jz_version {
  50        ID_JZ4740,
  51        ID_JZ4725B,
  52        ID_JZ4770,
  53        ID_JZ4780,
  54};
  55
  56struct ingenic_chip_info {
  57        unsigned int num_chips;
  58
  59        const struct group_desc *groups;
  60        unsigned int num_groups;
  61
  62        const struct function_desc *functions;
  63        unsigned int num_functions;
  64
  65        const u32 *pull_ups, *pull_downs;
  66};
  67
  68struct ingenic_pinctrl {
  69        struct device *dev;
  70        struct regmap *map;
  71        struct pinctrl_dev *pctl;
  72        struct pinctrl_pin_desc *pdesc;
  73        enum jz_version version;
  74
  75        const struct ingenic_chip_info *info;
  76};
  77
  78struct ingenic_gpio_chip {
  79        struct ingenic_pinctrl *jzpc;
  80        struct gpio_chip gc;
  81        struct irq_chip irq_chip;
  82        unsigned int irq, reg_base;
  83};
  84
  85static const u32 jz4740_pull_ups[4] = {
  86        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
  87};
  88
  89static const u32 jz4740_pull_downs[4] = {
  90        0x00000000, 0x00000000, 0x00000000, 0x00000000,
  91};
  92
  93static int jz4740_mmc_1bit_pins[] = { 0x69, 0x68, 0x6a, };
  94static int jz4740_mmc_4bit_pins[] = { 0x6b, 0x6c, 0x6d, };
  95static int jz4740_uart0_data_pins[] = { 0x7a, 0x79, };
  96static int jz4740_uart0_hwflow_pins[] = { 0x7e, 0x7f, };
  97static int jz4740_uart1_data_pins[] = { 0x7e, 0x7f, };
  98static int jz4740_lcd_8bit_pins[] = {
  99        0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x52, 0x53, 0x54,
 100};
 101static int jz4740_lcd_16bit_pins[] = {
 102        0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x55,
 103};
 104static int jz4740_lcd_18bit_pins[] = { 0x50, 0x51, };
 105static int jz4740_lcd_18bit_tft_pins[] = { 0x56, 0x57, 0x31, 0x32, };
 106static int jz4740_nand_cs1_pins[] = { 0x39, };
 107static int jz4740_nand_cs2_pins[] = { 0x3a, };
 108static int jz4740_nand_cs3_pins[] = { 0x3b, };
 109static int jz4740_nand_cs4_pins[] = { 0x3c, };
 110static int jz4740_pwm_pwm0_pins[] = { 0x77, };
 111static int jz4740_pwm_pwm1_pins[] = { 0x78, };
 112static int jz4740_pwm_pwm2_pins[] = { 0x79, };
 113static int jz4740_pwm_pwm3_pins[] = { 0x7a, };
 114static int jz4740_pwm_pwm4_pins[] = { 0x7b, };
 115static int jz4740_pwm_pwm5_pins[] = { 0x7c, };
 116static int jz4740_pwm_pwm6_pins[] = { 0x7e, };
 117static int jz4740_pwm_pwm7_pins[] = { 0x7f, };
 118
 119static int jz4740_mmc_1bit_funcs[] = { 0, 0, 0, };
 120static int jz4740_mmc_4bit_funcs[] = { 0, 0, 0, };
 121static int jz4740_uart0_data_funcs[] = { 1, 1, };
 122static int jz4740_uart0_hwflow_funcs[] = { 1, 1, };
 123static int jz4740_uart1_data_funcs[] = { 2, 2, };
 124static int jz4740_lcd_8bit_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
 125static int jz4740_lcd_16bit_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, };
 126static int jz4740_lcd_18bit_funcs[] = { 0, 0, };
 127static int jz4740_lcd_18bit_tft_funcs[] = { 0, 0, 0, 0, };
 128static int jz4740_nand_cs1_funcs[] = { 0, };
 129static int jz4740_nand_cs2_funcs[] = { 0, };
 130static int jz4740_nand_cs3_funcs[] = { 0, };
 131static int jz4740_nand_cs4_funcs[] = { 0, };
 132static int jz4740_pwm_pwm0_funcs[] = { 0, };
 133static int jz4740_pwm_pwm1_funcs[] = { 0, };
 134static int jz4740_pwm_pwm2_funcs[] = { 0, };
 135static int jz4740_pwm_pwm3_funcs[] = { 0, };
 136static int jz4740_pwm_pwm4_funcs[] = { 0, };
 137static int jz4740_pwm_pwm5_funcs[] = { 0, };
 138static int jz4740_pwm_pwm6_funcs[] = { 0, };
 139static int jz4740_pwm_pwm7_funcs[] = { 0, };
 140
 141#define INGENIC_PIN_GROUP(name, id)                     \
 142        {                                               \
 143                name,                                   \
 144                id##_pins,                              \
 145                ARRAY_SIZE(id##_pins),                  \
 146                id##_funcs,                             \
 147        }
 148
 149static const struct group_desc jz4740_groups[] = {
 150        INGENIC_PIN_GROUP("mmc-1bit", jz4740_mmc_1bit),
 151        INGENIC_PIN_GROUP("mmc-4bit", jz4740_mmc_4bit),
 152        INGENIC_PIN_GROUP("uart0-data", jz4740_uart0_data),
 153        INGENIC_PIN_GROUP("uart0-hwflow", jz4740_uart0_hwflow),
 154        INGENIC_PIN_GROUP("uart1-data", jz4740_uart1_data),
 155        INGENIC_PIN_GROUP("lcd-8bit", jz4740_lcd_8bit),
 156        INGENIC_PIN_GROUP("lcd-16bit", jz4740_lcd_16bit),
 157        INGENIC_PIN_GROUP("lcd-18bit", jz4740_lcd_18bit),
 158        INGENIC_PIN_GROUP("lcd-18bit-tft", jz4740_lcd_18bit_tft),
 159        { "lcd-no-pins", },
 160        INGENIC_PIN_GROUP("nand-cs1", jz4740_nand_cs1),
 161        INGENIC_PIN_GROUP("nand-cs2", jz4740_nand_cs2),
 162        INGENIC_PIN_GROUP("nand-cs3", jz4740_nand_cs3),
 163        INGENIC_PIN_GROUP("nand-cs4", jz4740_nand_cs4),
 164        INGENIC_PIN_GROUP("pwm0", jz4740_pwm_pwm0),
 165        INGENIC_PIN_GROUP("pwm1", jz4740_pwm_pwm1),
 166        INGENIC_PIN_GROUP("pwm2", jz4740_pwm_pwm2),
 167        INGENIC_PIN_GROUP("pwm3", jz4740_pwm_pwm3),
 168        INGENIC_PIN_GROUP("pwm4", jz4740_pwm_pwm4),
 169        INGENIC_PIN_GROUP("pwm5", jz4740_pwm_pwm5),
 170        INGENIC_PIN_GROUP("pwm6", jz4740_pwm_pwm6),
 171        INGENIC_PIN_GROUP("pwm7", jz4740_pwm_pwm7),
 172};
 173
 174static const char *jz4740_mmc_groups[] = { "mmc-1bit", "mmc-4bit", };
 175static const char *jz4740_uart0_groups[] = { "uart0-data", "uart0-hwflow", };
 176static const char *jz4740_uart1_groups[] = { "uart1-data", };
 177static const char *jz4740_lcd_groups[] = {
 178        "lcd-8bit", "lcd-16bit", "lcd-18bit", "lcd-18bit-tft", "lcd-no-pins",
 179};
 180static const char *jz4740_nand_groups[] = {
 181        "nand-cs1", "nand-cs2", "nand-cs3", "nand-cs4",
 182};
 183static const char *jz4740_pwm0_groups[] = { "pwm0", };
 184static const char *jz4740_pwm1_groups[] = { "pwm1", };
 185static const char *jz4740_pwm2_groups[] = { "pwm2", };
 186static const char *jz4740_pwm3_groups[] = { "pwm3", };
 187static const char *jz4740_pwm4_groups[] = { "pwm4", };
 188static const char *jz4740_pwm5_groups[] = { "pwm5", };
 189static const char *jz4740_pwm6_groups[] = { "pwm6", };
 190static const char *jz4740_pwm7_groups[] = { "pwm7", };
 191
 192static const struct function_desc jz4740_functions[] = {
 193        { "mmc", jz4740_mmc_groups, ARRAY_SIZE(jz4740_mmc_groups), },
 194        { "uart0", jz4740_uart0_groups, ARRAY_SIZE(jz4740_uart0_groups), },
 195        { "uart1", jz4740_uart1_groups, ARRAY_SIZE(jz4740_uart1_groups), },
 196        { "lcd", jz4740_lcd_groups, ARRAY_SIZE(jz4740_lcd_groups), },
 197        { "nand", jz4740_nand_groups, ARRAY_SIZE(jz4740_nand_groups), },
 198        { "pwm0", jz4740_pwm0_groups, ARRAY_SIZE(jz4740_pwm0_groups), },
 199        { "pwm1", jz4740_pwm1_groups, ARRAY_SIZE(jz4740_pwm1_groups), },
 200        { "pwm2", jz4740_pwm2_groups, ARRAY_SIZE(jz4740_pwm2_groups), },
 201        { "pwm3", jz4740_pwm3_groups, ARRAY_SIZE(jz4740_pwm3_groups), },
 202        { "pwm4", jz4740_pwm4_groups, ARRAY_SIZE(jz4740_pwm4_groups), },
 203        { "pwm5", jz4740_pwm5_groups, ARRAY_SIZE(jz4740_pwm5_groups), },
 204        { "pwm6", jz4740_pwm6_groups, ARRAY_SIZE(jz4740_pwm6_groups), },
 205        { "pwm7", jz4740_pwm7_groups, ARRAY_SIZE(jz4740_pwm7_groups), },
 206};
 207
 208static const struct ingenic_chip_info jz4740_chip_info = {
 209        .num_chips = 4,
 210        .groups = jz4740_groups,
 211        .num_groups = ARRAY_SIZE(jz4740_groups),
 212        .functions = jz4740_functions,
 213        .num_functions = ARRAY_SIZE(jz4740_functions),
 214        .pull_ups = jz4740_pull_ups,
 215        .pull_downs = jz4740_pull_downs,
 216};
 217
 218static int jz4725b_mmc0_1bit_pins[] = { 0x48, 0x49, 0x5c, };
 219static int jz4725b_mmc0_4bit_pins[] = { 0x5d, 0x5b, 0x56, };
 220static int jz4725b_mmc1_1bit_pins[] = { 0x7a, 0x7b, 0x7c, };
 221static int jz4725b_mmc1_4bit_pins[] = { 0x7d, 0x7e, 0x7f, };
 222static int jz4725b_uart_data_pins[] = { 0x4c, 0x4d, };
 223static int jz4725b_nand_cs1_pins[] = { 0x55, };
 224static int jz4725b_nand_cs2_pins[] = { 0x56, };
 225static int jz4725b_nand_cs3_pins[] = { 0x57, };
 226static int jz4725b_nand_cs4_pins[] = { 0x58, };
 227static int jz4725b_nand_cle_ale_pins[] = { 0x48, 0x49 };
 228static int jz4725b_nand_fre_fwe_pins[] = { 0x5c, 0x5d };
 229static int jz4725b_pwm_pwm0_pins[] = { 0x4a, };
 230static int jz4725b_pwm_pwm1_pins[] = { 0x4b, };
 231static int jz4725b_pwm_pwm2_pins[] = { 0x4c, };
 232static int jz4725b_pwm_pwm3_pins[] = { 0x4d, };
 233static int jz4725b_pwm_pwm4_pins[] = { 0x4e, };
 234static int jz4725b_pwm_pwm5_pins[] = { 0x4f, };
 235static int jz4725b_lcd_8bit_pins[] = {
 236        0x72, 0x73, 0x74,
 237        0x60, 0x61, 0x62, 0x63,
 238        0x64, 0x65, 0x66, 0x67,
 239};
 240static int jz4725b_lcd_16bit_pins[] = {
 241        0x68, 0x69, 0x6a, 0x6b,
 242        0x6c, 0x6d, 0x6e, 0x6f,
 243};
 244static int jz4725b_lcd_18bit_pins[] = { 0x70, 0x71, };
 245static int jz4725b_lcd_24bit_pins[] = { 0x76, 0x77, 0x78, 0x79, };
 246static int jz4725b_lcd_special_pins[] = { 0x76, 0x77, 0x78, 0x79, };
 247static int jz4725b_lcd_generic_pins[] = { 0x75, };
 248
 249static int jz4725b_mmc0_1bit_funcs[] = { 1, 1, 1, };
 250static int jz4725b_mmc0_4bit_funcs[] = { 1, 0, 1, };
 251static int jz4725b_mmc1_1bit_funcs[] = { 0, 0, 0, };
 252static int jz4725b_mmc1_4bit_funcs[] = { 0, 0, 0, };
 253static int jz4725b_uart_data_funcs[] = { 1, 1, };
 254static int jz4725b_nand_cs1_funcs[] = { 0, };
 255static int jz4725b_nand_cs2_funcs[] = { 0, };
 256static int jz4725b_nand_cs3_funcs[] = { 0, };
 257static int jz4725b_nand_cs4_funcs[] = { 0, };
 258static int jz4725b_nand_cle_ale_funcs[] = { 0, 0, };
 259static int jz4725b_nand_fre_fwe_funcs[] = { 0, 0, };
 260static int jz4725b_pwm_pwm0_funcs[] = { 0, };
 261static int jz4725b_pwm_pwm1_funcs[] = { 0, };
 262static int jz4725b_pwm_pwm2_funcs[] = { 0, };
 263static int jz4725b_pwm_pwm3_funcs[] = { 0, };
 264static int jz4725b_pwm_pwm4_funcs[] = { 0, };
 265static int jz4725b_pwm_pwm5_funcs[] = { 0, };
 266static int jz4725b_lcd_8bit_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
 267static int jz4725b_lcd_16bit_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, };
 268static int jz4725b_lcd_18bit_funcs[] = { 0, 0, };
 269static int jz4725b_lcd_24bit_funcs[] = { 1, 1, 1, 1, };
 270static int jz4725b_lcd_special_funcs[] = { 0, 0, 0, 0, };
 271static int jz4725b_lcd_generic_funcs[] = { 0, };
 272
 273static const struct group_desc jz4725b_groups[] = {
 274        INGENIC_PIN_GROUP("mmc0-1bit", jz4725b_mmc0_1bit),
 275        INGENIC_PIN_GROUP("mmc0-4bit", jz4725b_mmc0_4bit),
 276        INGENIC_PIN_GROUP("mmc1-1bit", jz4725b_mmc1_1bit),
 277        INGENIC_PIN_GROUP("mmc1-4bit", jz4725b_mmc1_4bit),
 278        INGENIC_PIN_GROUP("uart-data", jz4725b_uart_data),
 279        INGENIC_PIN_GROUP("nand-cs1", jz4725b_nand_cs1),
 280        INGENIC_PIN_GROUP("nand-cs2", jz4725b_nand_cs2),
 281        INGENIC_PIN_GROUP("nand-cs3", jz4725b_nand_cs3),
 282        INGENIC_PIN_GROUP("nand-cs4", jz4725b_nand_cs4),
 283        INGENIC_PIN_GROUP("nand-cle-ale", jz4725b_nand_cle_ale),
 284        INGENIC_PIN_GROUP("nand-fre-fwe", jz4725b_nand_fre_fwe),
 285        INGENIC_PIN_GROUP("pwm0", jz4725b_pwm_pwm0),
 286        INGENIC_PIN_GROUP("pwm1", jz4725b_pwm_pwm1),
 287        INGENIC_PIN_GROUP("pwm2", jz4725b_pwm_pwm2),
 288        INGENIC_PIN_GROUP("pwm3", jz4725b_pwm_pwm3),
 289        INGENIC_PIN_GROUP("pwm4", jz4725b_pwm_pwm4),
 290        INGENIC_PIN_GROUP("pwm5", jz4725b_pwm_pwm5),
 291        INGENIC_PIN_GROUP("lcd-8bit", jz4725b_lcd_8bit),
 292        INGENIC_PIN_GROUP("lcd-16bit", jz4725b_lcd_16bit),
 293        INGENIC_PIN_GROUP("lcd-18bit", jz4725b_lcd_18bit),
 294        INGENIC_PIN_GROUP("lcd-24bit", jz4725b_lcd_24bit),
 295        INGENIC_PIN_GROUP("lcd-special", jz4725b_lcd_special),
 296        INGENIC_PIN_GROUP("lcd-generic", jz4725b_lcd_generic),
 297};
 298
 299static const char *jz4725b_mmc0_groups[] = { "mmc0-1bit", "mmc0-4bit", };
 300static const char *jz4725b_mmc1_groups[] = { "mmc1-1bit", "mmc1-4bit", };
 301static const char *jz4725b_uart_groups[] = { "uart-data", };
 302static const char *jz4725b_nand_groups[] = {
 303        "nand-cs1", "nand-cs2", "nand-cs3", "nand-cs4",
 304        "nand-cle-ale", "nand-fre-fwe",
 305};
 306static const char *jz4725b_pwm0_groups[] = { "pwm0", };
 307static const char *jz4725b_pwm1_groups[] = { "pwm1", };
 308static const char *jz4725b_pwm2_groups[] = { "pwm2", };
 309static const char *jz4725b_pwm3_groups[] = { "pwm3", };
 310static const char *jz4725b_pwm4_groups[] = { "pwm4", };
 311static const char *jz4725b_pwm5_groups[] = { "pwm5", };
 312static const char *jz4725b_lcd_groups[] = {
 313        "lcd-8bit", "lcd-16bit", "lcd-18bit", "lcd-24bit",
 314        "lcd-special", "lcd-generic",
 315};
 316
 317static const struct function_desc jz4725b_functions[] = {
 318        { "mmc0", jz4725b_mmc0_groups, ARRAY_SIZE(jz4725b_mmc0_groups), },
 319        { "mmc1", jz4725b_mmc1_groups, ARRAY_SIZE(jz4725b_mmc1_groups), },
 320        { "uart", jz4725b_uart_groups, ARRAY_SIZE(jz4725b_uart_groups), },
 321        { "nand", jz4725b_nand_groups, ARRAY_SIZE(jz4725b_nand_groups), },
 322        { "pwm0", jz4725b_pwm0_groups, ARRAY_SIZE(jz4725b_pwm0_groups), },
 323        { "pwm1", jz4725b_pwm1_groups, ARRAY_SIZE(jz4725b_pwm1_groups), },
 324        { "pwm2", jz4725b_pwm2_groups, ARRAY_SIZE(jz4725b_pwm2_groups), },
 325        { "pwm3", jz4725b_pwm3_groups, ARRAY_SIZE(jz4725b_pwm3_groups), },
 326        { "pwm4", jz4725b_pwm4_groups, ARRAY_SIZE(jz4725b_pwm4_groups), },
 327        { "pwm5", jz4725b_pwm5_groups, ARRAY_SIZE(jz4725b_pwm5_groups), },
 328        { "lcd", jz4725b_lcd_groups, ARRAY_SIZE(jz4725b_lcd_groups), },
 329};
 330
 331static const struct ingenic_chip_info jz4725b_chip_info = {
 332        .num_chips = 4,
 333        .groups = jz4725b_groups,
 334        .num_groups = ARRAY_SIZE(jz4725b_groups),
 335        .functions = jz4725b_functions,
 336        .num_functions = ARRAY_SIZE(jz4725b_functions),
 337        .pull_ups = jz4740_pull_ups,
 338        .pull_downs = jz4740_pull_downs,
 339};
 340
 341static const u32 jz4770_pull_ups[6] = {
 342        0x3fffffff, 0xfff0030c, 0xffffffff, 0xffff4fff, 0xfffffb7c, 0xffa7f00f,
 343};
 344
 345static const u32 jz4770_pull_downs[6] = {
 346        0x00000000, 0x000f0c03, 0x00000000, 0x0000b000, 0x00000483, 0x00580ff0,
 347};
 348
 349static int jz4770_uart0_data_pins[] = { 0xa0, 0xa3, };
 350static int jz4770_uart0_hwflow_pins[] = { 0xa1, 0xa2, };
 351static int jz4770_uart1_data_pins[] = { 0x7a, 0x7c, };
 352static int jz4770_uart1_hwflow_pins[] = { 0x7b, 0x7d, };
 353static int jz4770_uart2_data_pins[] = { 0x5c, 0x5e, };
 354static int jz4770_uart2_hwflow_pins[] = { 0x5d, 0x5f, };
 355static int jz4770_uart3_data_pins[] = { 0x6c, 0x85, };
 356static int jz4770_uart3_hwflow_pins[] = { 0x88, 0x89, };
 357static int jz4770_mmc0_1bit_a_pins[] = { 0x12, 0x13, 0x14, };
 358static int jz4770_mmc0_4bit_a_pins[] = { 0x15, 0x16, 0x17, };
 359static int jz4770_mmc0_1bit_e_pins[] = { 0x9c, 0x9d, 0x94, };
 360static int jz4770_mmc0_4bit_e_pins[] = { 0x95, 0x96, 0x97, };
 361static int jz4770_mmc0_8bit_e_pins[] = { 0x98, 0x99, 0x9a, 0x9b, };
 362static int jz4770_mmc1_1bit_d_pins[] = { 0x78, 0x79, 0x74, };
 363static int jz4770_mmc1_4bit_d_pins[] = { 0x75, 0x76, 0x77, };
 364static int jz4770_mmc1_1bit_e_pins[] = { 0x9c, 0x9d, 0x94, };
 365static int jz4770_mmc1_4bit_e_pins[] = { 0x95, 0x96, 0x97, };
 366static int jz4770_mmc1_8bit_e_pins[] = { 0x98, 0x99, 0x9a, 0x9b, };
 367static int jz4770_mmc2_1bit_b_pins[] = { 0x3c, 0x3d, 0x34, };
 368static int jz4770_mmc2_4bit_b_pins[] = { 0x35, 0x3e, 0x3f, };
 369static int jz4770_mmc2_1bit_e_pins[] = { 0x9c, 0x9d, 0x94, };
 370static int jz4770_mmc2_4bit_e_pins[] = { 0x95, 0x96, 0x97, };
 371static int jz4770_mmc2_8bit_e_pins[] = { 0x98, 0x99, 0x9a, 0x9b, };
 372static int jz4770_nemc_8bit_data_pins[] = {
 373        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
 374};
 375static int jz4770_nemc_16bit_data_pins[] = {
 376        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
 377};
 378static int jz4770_nemc_cle_ale_pins[] = { 0x20, 0x21, };
 379static int jz4770_nemc_addr_pins[] = { 0x22, 0x23, 0x24, 0x25, };
 380static int jz4770_nemc_rd_we_pins[] = { 0x10, 0x11, };
 381static int jz4770_nemc_frd_fwe_pins[] = { 0x12, 0x13, };
 382static int jz4770_nemc_wait_pins[] = { 0x1b, };
 383static int jz4770_nemc_cs1_pins[] = { 0x15, };
 384static int jz4770_nemc_cs2_pins[] = { 0x16, };
 385static int jz4770_nemc_cs3_pins[] = { 0x17, };
 386static int jz4770_nemc_cs4_pins[] = { 0x18, };
 387static int jz4770_nemc_cs5_pins[] = { 0x19, };
 388static int jz4770_nemc_cs6_pins[] = { 0x1a, };
 389static int jz4770_i2c0_pins[] = { 0x7e, 0x7f, };
 390static int jz4770_i2c1_pins[] = { 0x9e, 0x9f, };
 391static int jz4770_i2c2_pins[] = { 0xb0, 0xb1, };
 392static int jz4770_cim_8bit_pins[] = {
 393        0x26, 0x27, 0x28, 0x29,
 394        0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
 395};
 396static int jz4770_cim_12bit_pins[] = {
 397        0x32, 0x33, 0xb0, 0xb1,
 398};
 399static int jz4770_lcd_24bit_pins[] = {
 400        0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
 401        0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
 402        0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
 403        0x58, 0x59, 0x5a, 0x5b,
 404};
 405static int jz4770_pwm_pwm0_pins[] = { 0x80, };
 406static int jz4770_pwm_pwm1_pins[] = { 0x81, };
 407static int jz4770_pwm_pwm2_pins[] = { 0x82, };
 408static int jz4770_pwm_pwm3_pins[] = { 0x83, };
 409static int jz4770_pwm_pwm4_pins[] = { 0x84, };
 410static int jz4770_pwm_pwm5_pins[] = { 0x85, };
 411static int jz4770_pwm_pwm6_pins[] = { 0x6a, };
 412static int jz4770_pwm_pwm7_pins[] = { 0x6b, };
 413static int jz4770_mac_rmii_pins[] = {
 414        0xa9, 0xab, 0xaa, 0xac, 0xa5, 0xa4, 0xad, 0xae, 0xa6, 0xa8,
 415};
 416static int jz4770_mac_mii_pins[] = { 0xa7, 0xaf, };
 417
 418static int jz4770_uart0_data_funcs[] = { 0, 0, };
 419static int jz4770_uart0_hwflow_funcs[] = { 0, 0, };
 420static int jz4770_uart1_data_funcs[] = { 0, 0, };
 421static int jz4770_uart1_hwflow_funcs[] = { 0, 0, };
 422static int jz4770_uart2_data_funcs[] = { 0, 0, };
 423static int jz4770_uart2_hwflow_funcs[] = { 0, 0, };
 424static int jz4770_uart3_data_funcs[] = { 0, 1, };
 425static int jz4770_uart3_hwflow_funcs[] = { 0, 0, };
 426static int jz4770_mmc0_1bit_a_funcs[] = { 1, 1, 0, };
 427static int jz4770_mmc0_4bit_a_funcs[] = { 1, 1, 1, };
 428static int jz4770_mmc0_1bit_e_funcs[] = { 0, 0, 0, };
 429static int jz4770_mmc0_4bit_e_funcs[] = { 0, 0, 0, };
 430static int jz4770_mmc0_8bit_e_funcs[] = { 0, 0, 0, 0, };
 431static int jz4770_mmc1_1bit_d_funcs[] = { 0, 0, 0, };
 432static int jz4770_mmc1_4bit_d_funcs[] = { 0, 0, 0, };
 433static int jz4770_mmc1_1bit_e_funcs[] = { 1, 1, 1, };
 434static int jz4770_mmc1_4bit_e_funcs[] = { 1, 1, 1, };
 435static int jz4770_mmc1_8bit_e_funcs[] = { 1, 1, 1, 1, };
 436static int jz4770_mmc2_1bit_b_funcs[] = { 0, 0, 0, };
 437static int jz4770_mmc2_4bit_b_funcs[] = { 0, 0, 0, };
 438static int jz4770_mmc2_1bit_e_funcs[] = { 2, 2, 2, };
 439static int jz4770_mmc2_4bit_e_funcs[] = { 2, 2, 2, };
 440static int jz4770_mmc2_8bit_e_funcs[] = { 2, 2, 2, 2, };
 441static int jz4770_nemc_8bit_data_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, };
 442static int jz4770_nemc_16bit_data_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, };
 443static int jz4770_nemc_cle_ale_funcs[] = { 0, 0, };
 444static int jz4770_nemc_addr_funcs[] = { 0, 0, 0, 0, };
 445static int jz4770_nemc_rd_we_funcs[] = { 0, 0, };
 446static int jz4770_nemc_frd_fwe_funcs[] = { 0, 0, };
 447static int jz4770_nemc_wait_funcs[] = { 0, };
 448static int jz4770_nemc_cs1_funcs[] = { 0, };
 449static int jz4770_nemc_cs2_funcs[] = { 0, };
 450static int jz4770_nemc_cs3_funcs[] = { 0, };
 451static int jz4770_nemc_cs4_funcs[] = { 0, };
 452static int jz4770_nemc_cs5_funcs[] = { 0, };
 453static int jz4770_nemc_cs6_funcs[] = { 0, };
 454static int jz4770_i2c0_funcs[] = { 0, 0, };
 455static int jz4770_i2c1_funcs[] = { 0, 0, };
 456static int jz4770_i2c2_funcs[] = { 2, 2, };
 457static int jz4770_cim_8bit_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
 458static int jz4770_cim_12bit_funcs[] = { 0, 0, 0, 0, };
 459static int jz4770_lcd_24bit_funcs[] = {
 460        0, 0, 0, 0, 0, 0, 0, 0,
 461        0, 0, 0, 0, 0, 0, 0, 0,
 462        0, 0, 0, 0, 0, 0, 0, 0,
 463        0, 0, 0, 0,
 464};
 465static int jz4770_pwm_pwm0_funcs[] = { 0, };
 466static int jz4770_pwm_pwm1_funcs[] = { 0, };
 467static int jz4770_pwm_pwm2_funcs[] = { 0, };
 468static int jz4770_pwm_pwm3_funcs[] = { 0, };
 469static int jz4770_pwm_pwm4_funcs[] = { 0, };
 470static int jz4770_pwm_pwm5_funcs[] = { 0, };
 471static int jz4770_pwm_pwm6_funcs[] = { 0, };
 472static int jz4770_pwm_pwm7_funcs[] = { 0, };
 473static int jz4770_mac_rmii_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
 474static int jz4770_mac_mii_funcs[] = { 0, 0, };
 475
 476static const struct group_desc jz4770_groups[] = {
 477        INGENIC_PIN_GROUP("uart0-data", jz4770_uart0_data),
 478        INGENIC_PIN_GROUP("uart0-hwflow", jz4770_uart0_hwflow),
 479        INGENIC_PIN_GROUP("uart1-data", jz4770_uart1_data),
 480        INGENIC_PIN_GROUP("uart1-hwflow", jz4770_uart1_hwflow),
 481        INGENIC_PIN_GROUP("uart2-data", jz4770_uart2_data),
 482        INGENIC_PIN_GROUP("uart2-hwflow", jz4770_uart2_hwflow),
 483        INGENIC_PIN_GROUP("uart3-data", jz4770_uart3_data),
 484        INGENIC_PIN_GROUP("uart3-hwflow", jz4770_uart3_hwflow),
 485        INGENIC_PIN_GROUP("mmc0-1bit-a", jz4770_mmc0_1bit_a),
 486        INGENIC_PIN_GROUP("mmc0-4bit-a", jz4770_mmc0_4bit_a),
 487        INGENIC_PIN_GROUP("mmc0-1bit-e", jz4770_mmc0_1bit_e),
 488        INGENIC_PIN_GROUP("mmc0-4bit-e", jz4770_mmc0_4bit_e),
 489        INGENIC_PIN_GROUP("mmc0-8bit-e", jz4770_mmc0_8bit_e),
 490        INGENIC_PIN_GROUP("mmc1-1bit-d", jz4770_mmc1_1bit_d),
 491        INGENIC_PIN_GROUP("mmc1-4bit-d", jz4770_mmc1_4bit_d),
 492        INGENIC_PIN_GROUP("mmc1-1bit-e", jz4770_mmc1_1bit_e),
 493        INGENIC_PIN_GROUP("mmc1-4bit-e", jz4770_mmc1_4bit_e),
 494        INGENIC_PIN_GROUP("mmc1-8bit-e", jz4770_mmc1_8bit_e),
 495        INGENIC_PIN_GROUP("mmc2-1bit-b", jz4770_mmc2_1bit_b),
 496        INGENIC_PIN_GROUP("mmc2-4bit-b", jz4770_mmc2_4bit_b),
 497        INGENIC_PIN_GROUP("mmc2-1bit-e", jz4770_mmc2_1bit_e),
 498        INGENIC_PIN_GROUP("mmc2-4bit-e", jz4770_mmc2_4bit_e),
 499        INGENIC_PIN_GROUP("mmc2-8bit-e", jz4770_mmc2_8bit_e),
 500        INGENIC_PIN_GROUP("nemc-8bit-data", jz4770_nemc_8bit_data),
 501        INGENIC_PIN_GROUP("nemc-16bit-data", jz4770_nemc_16bit_data),
 502        INGENIC_PIN_GROUP("nemc-cle-ale", jz4770_nemc_cle_ale),
 503        INGENIC_PIN_GROUP("nemc-addr", jz4770_nemc_addr),
 504        INGENIC_PIN_GROUP("nemc-rd-we", jz4770_nemc_rd_we),
 505        INGENIC_PIN_GROUP("nemc-frd-fwe", jz4770_nemc_frd_fwe),
 506        INGENIC_PIN_GROUP("nemc-wait", jz4770_nemc_wait),
 507        INGENIC_PIN_GROUP("nemc-cs1", jz4770_nemc_cs1),
 508        INGENIC_PIN_GROUP("nemc-cs2", jz4770_nemc_cs2),
 509        INGENIC_PIN_GROUP("nemc-cs3", jz4770_nemc_cs3),
 510        INGENIC_PIN_GROUP("nemc-cs4", jz4770_nemc_cs4),
 511        INGENIC_PIN_GROUP("nemc-cs5", jz4770_nemc_cs5),
 512        INGENIC_PIN_GROUP("nemc-cs6", jz4770_nemc_cs6),
 513        INGENIC_PIN_GROUP("i2c0-data", jz4770_i2c0),
 514        INGENIC_PIN_GROUP("i2c1-data", jz4770_i2c1),
 515        INGENIC_PIN_GROUP("i2c2-data", jz4770_i2c2),
 516        INGENIC_PIN_GROUP("cim-data-8bit", jz4770_cim_8bit),
 517        INGENIC_PIN_GROUP("cim-data-12bit", jz4770_cim_12bit),
 518        INGENIC_PIN_GROUP("lcd-24bit", jz4770_lcd_24bit),
 519        { "lcd-no-pins", },
 520        INGENIC_PIN_GROUP("pwm0", jz4770_pwm_pwm0),
 521        INGENIC_PIN_GROUP("pwm1", jz4770_pwm_pwm1),
 522        INGENIC_PIN_GROUP("pwm2", jz4770_pwm_pwm2),
 523        INGENIC_PIN_GROUP("pwm3", jz4770_pwm_pwm3),
 524        INGENIC_PIN_GROUP("pwm4", jz4770_pwm_pwm4),
 525        INGENIC_PIN_GROUP("pwm5", jz4770_pwm_pwm5),
 526        INGENIC_PIN_GROUP("pwm6", jz4770_pwm_pwm6),
 527        INGENIC_PIN_GROUP("pwm7", jz4770_pwm_pwm7),
 528        INGENIC_PIN_GROUP("mac-rmii", jz4770_mac_rmii),
 529        INGENIC_PIN_GROUP("mac-mii", jz4770_mac_mii),
 530};
 531
 532static const char *jz4770_uart0_groups[] = { "uart0-data", "uart0-hwflow", };
 533static const char *jz4770_uart1_groups[] = { "uart1-data", "uart1-hwflow", };
 534static const char *jz4770_uart2_groups[] = { "uart2-data", "uart2-hwflow", };
 535static const char *jz4770_uart3_groups[] = { "uart3-data", "uart3-hwflow", };
 536static const char *jz4770_mmc0_groups[] = {
 537        "mmc0-1bit-a", "mmc0-4bit-a",
 538        "mmc0-1bit-e", "mmc0-4bit-e", "mmc0-8bit-e",
 539};
 540static const char *jz4770_mmc1_groups[] = {
 541        "mmc1-1bit-d", "mmc1-4bit-d",
 542        "mmc1-1bit-e", "mmc1-4bit-e", "mmc1-8bit-e",
 543};
 544static const char *jz4770_mmc2_groups[] = {
 545        "mmc2-1bit-b", "mmc2-4bit-b",
 546        "mmc2-1bit-e", "mmc2-4bit-e", "mmc2-8bit-e",
 547};
 548static const char *jz4770_nemc_groups[] = {
 549        "nemc-8bit-data", "nemc-16bit-data", "nemc-cle-ale",
 550        "nemc-addr", "nemc-rd-we", "nemc-frd-fwe", "nemc-wait",
 551};
 552static const char *jz4770_cs1_groups[] = { "nemc-cs1", };
 553static const char *jz4770_cs2_groups[] = { "nemc-cs2", };
 554static const char *jz4770_cs3_groups[] = { "nemc-cs3", };
 555static const char *jz4770_cs4_groups[] = { "nemc-cs4", };
 556static const char *jz4770_cs5_groups[] = { "nemc-cs5", };
 557static const char *jz4770_cs6_groups[] = { "nemc-cs6", };
 558static const char *jz4770_i2c0_groups[] = { "i2c0-data", };
 559static const char *jz4770_i2c1_groups[] = { "i2c1-data", };
 560static const char *jz4770_i2c2_groups[] = { "i2c2-data", };
 561static const char *jz4770_cim_groups[] = { "cim-data-8bit", "cim-data-12bit", };
 562static const char *jz4770_lcd_groups[] = { "lcd-24bit", "lcd-no-pins", };
 563static const char *jz4770_pwm0_groups[] = { "pwm0", };
 564static const char *jz4770_pwm1_groups[] = { "pwm1", };
 565static const char *jz4770_pwm2_groups[] = { "pwm2", };
 566static const char *jz4770_pwm3_groups[] = { "pwm3", };
 567static const char *jz4770_pwm4_groups[] = { "pwm4", };
 568static const char *jz4770_pwm5_groups[] = { "pwm5", };
 569static const char *jz4770_pwm6_groups[] = { "pwm6", };
 570static const char *jz4770_pwm7_groups[] = { "pwm7", };
 571static const char *jz4770_mac_groups[] = { "mac-rmii", "mac-mii", };
 572
 573static const struct function_desc jz4770_functions[] = {
 574        { "uart0", jz4770_uart0_groups, ARRAY_SIZE(jz4770_uart0_groups), },
 575        { "uart1", jz4770_uart1_groups, ARRAY_SIZE(jz4770_uart1_groups), },
 576        { "uart2", jz4770_uart2_groups, ARRAY_SIZE(jz4770_uart2_groups), },
 577        { "uart3", jz4770_uart3_groups, ARRAY_SIZE(jz4770_uart3_groups), },
 578        { "mmc0", jz4770_mmc0_groups, ARRAY_SIZE(jz4770_mmc0_groups), },
 579        { "mmc1", jz4770_mmc1_groups, ARRAY_SIZE(jz4770_mmc1_groups), },
 580        { "mmc2", jz4770_mmc2_groups, ARRAY_SIZE(jz4770_mmc2_groups), },
 581        { "nemc", jz4770_nemc_groups, ARRAY_SIZE(jz4770_nemc_groups), },
 582        { "nemc-cs1", jz4770_cs1_groups, ARRAY_SIZE(jz4770_cs1_groups), },
 583        { "nemc-cs2", jz4770_cs2_groups, ARRAY_SIZE(jz4770_cs2_groups), },
 584        { "nemc-cs3", jz4770_cs3_groups, ARRAY_SIZE(jz4770_cs3_groups), },
 585        { "nemc-cs4", jz4770_cs4_groups, ARRAY_SIZE(jz4770_cs4_groups), },
 586        { "nemc-cs5", jz4770_cs5_groups, ARRAY_SIZE(jz4770_cs5_groups), },
 587        { "nemc-cs6", jz4770_cs6_groups, ARRAY_SIZE(jz4770_cs6_groups), },
 588        { "i2c0", jz4770_i2c0_groups, ARRAY_SIZE(jz4770_i2c0_groups), },
 589        { "i2c1", jz4770_i2c1_groups, ARRAY_SIZE(jz4770_i2c1_groups), },
 590        { "i2c2", jz4770_i2c2_groups, ARRAY_SIZE(jz4770_i2c2_groups), },
 591        { "cim", jz4770_cim_groups, ARRAY_SIZE(jz4770_cim_groups), },
 592        { "lcd", jz4770_lcd_groups, ARRAY_SIZE(jz4770_lcd_groups), },
 593        { "pwm0", jz4770_pwm0_groups, ARRAY_SIZE(jz4770_pwm0_groups), },
 594        { "pwm1", jz4770_pwm1_groups, ARRAY_SIZE(jz4770_pwm1_groups), },
 595        { "pwm2", jz4770_pwm2_groups, ARRAY_SIZE(jz4770_pwm2_groups), },
 596        { "pwm3", jz4770_pwm3_groups, ARRAY_SIZE(jz4770_pwm3_groups), },
 597        { "pwm4", jz4770_pwm4_groups, ARRAY_SIZE(jz4770_pwm4_groups), },
 598        { "pwm5", jz4770_pwm5_groups, ARRAY_SIZE(jz4770_pwm5_groups), },
 599        { "pwm6", jz4770_pwm6_groups, ARRAY_SIZE(jz4770_pwm6_groups), },
 600        { "pwm7", jz4770_pwm7_groups, ARRAY_SIZE(jz4770_pwm7_groups), },
 601        { "mac", jz4770_mac_groups, ARRAY_SIZE(jz4770_mac_groups), },
 602};
 603
 604static const struct ingenic_chip_info jz4770_chip_info = {
 605        .num_chips = 6,
 606        .groups = jz4770_groups,
 607        .num_groups = ARRAY_SIZE(jz4770_groups),
 608        .functions = jz4770_functions,
 609        .num_functions = ARRAY_SIZE(jz4770_functions),
 610        .pull_ups = jz4770_pull_ups,
 611        .pull_downs = jz4770_pull_downs,
 612};
 613
 614static int jz4780_uart2_data_pins[] = { 0x66, 0x67, };
 615static int jz4780_uart2_hwflow_pins[] = { 0x65, 0x64, };
 616static int jz4780_uart4_data_pins[] = { 0x54, 0x4a, };
 617static int jz4780_mmc0_8bit_a_pins[] = { 0x04, 0x05, 0x06, 0x07, 0x18, };
 618static int jz4780_i2c3_pins[] = { 0x6a, 0x6b, };
 619static int jz4780_i2c4_e_pins[] = { 0x8c, 0x8d, };
 620static int jz4780_i2c4_f_pins[] = { 0xb9, 0xb8, };
 621
 622static int jz4780_uart2_data_funcs[] = { 1, 1, };
 623static int jz4780_uart2_hwflow_funcs[] = { 1, 1, };
 624static int jz4780_uart4_data_funcs[] = { 2, 2, };
 625static int jz4780_mmc0_8bit_a_funcs[] = { 1, 1, 1, 1, 1, };
 626static int jz4780_i2c3_funcs[] = { 1, 1, };
 627static int jz4780_i2c4_e_funcs[] = { 1, 1, };
 628static int jz4780_i2c4_f_funcs[] = { 1, 1, };
 629
 630static const struct group_desc jz4780_groups[] = {
 631        INGENIC_PIN_GROUP("uart0-data", jz4770_uart0_data),
 632        INGENIC_PIN_GROUP("uart0-hwflow", jz4770_uart0_hwflow),
 633        INGENIC_PIN_GROUP("uart1-data", jz4770_uart1_data),
 634        INGENIC_PIN_GROUP("uart1-hwflow", jz4770_uart1_hwflow),
 635        INGENIC_PIN_GROUP("uart2-data", jz4780_uart2_data),
 636        INGENIC_PIN_GROUP("uart2-hwflow", jz4780_uart2_hwflow),
 637        INGENIC_PIN_GROUP("uart3-data", jz4770_uart3_data),
 638        INGENIC_PIN_GROUP("uart3-hwflow", jz4770_uart3_hwflow),
 639        INGENIC_PIN_GROUP("uart4-data", jz4780_uart4_data),
 640        INGENIC_PIN_GROUP("mmc0-1bit-a", jz4770_mmc0_1bit_a),
 641        INGENIC_PIN_GROUP("mmc0-4bit-a", jz4770_mmc0_4bit_a),
 642        INGENIC_PIN_GROUP("mmc0-8bit-a", jz4780_mmc0_8bit_a),
 643        INGENIC_PIN_GROUP("mmc0-1bit-e", jz4770_mmc0_1bit_e),
 644        INGENIC_PIN_GROUP("mmc0-4bit-e", jz4770_mmc0_4bit_e),
 645        INGENIC_PIN_GROUP("mmc1-1bit-d", jz4770_mmc1_1bit_d),
 646        INGENIC_PIN_GROUP("mmc1-4bit-d", jz4770_mmc1_4bit_d),
 647        INGENIC_PIN_GROUP("mmc1-1bit-e", jz4770_mmc1_1bit_e),
 648        INGENIC_PIN_GROUP("mmc1-4bit-e", jz4770_mmc1_4bit_e),
 649        INGENIC_PIN_GROUP("mmc2-1bit-b", jz4770_mmc2_1bit_b),
 650        INGENIC_PIN_GROUP("mmc2-4bit-b", jz4770_mmc2_4bit_b),
 651        INGENIC_PIN_GROUP("mmc2-1bit-e", jz4770_mmc2_1bit_e),
 652        INGENIC_PIN_GROUP("mmc2-4bit-e", jz4770_mmc2_4bit_e),
 653        INGENIC_PIN_GROUP("nemc-data", jz4770_nemc_8bit_data),
 654        INGENIC_PIN_GROUP("nemc-cle-ale", jz4770_nemc_cle_ale),
 655        INGENIC_PIN_GROUP("nemc-addr", jz4770_nemc_addr),
 656        INGENIC_PIN_GROUP("nemc-rd-we", jz4770_nemc_rd_we),
 657        INGENIC_PIN_GROUP("nemc-frd-fwe", jz4770_nemc_frd_fwe),
 658        INGENIC_PIN_GROUP("nemc-wait", jz4770_nemc_wait),
 659        INGENIC_PIN_GROUP("nemc-cs1", jz4770_nemc_cs1),
 660        INGENIC_PIN_GROUP("nemc-cs2", jz4770_nemc_cs2),
 661        INGENIC_PIN_GROUP("nemc-cs3", jz4770_nemc_cs3),
 662        INGENIC_PIN_GROUP("nemc-cs4", jz4770_nemc_cs4),
 663        INGENIC_PIN_GROUP("nemc-cs5", jz4770_nemc_cs5),
 664        INGENIC_PIN_GROUP("nemc-cs6", jz4770_nemc_cs6),
 665        INGENIC_PIN_GROUP("i2c0-data", jz4770_i2c0),
 666        INGENIC_PIN_GROUP("i2c1-data", jz4770_i2c1),
 667        INGENIC_PIN_GROUP("i2c2-data", jz4770_i2c2),
 668        INGENIC_PIN_GROUP("i2c3-data", jz4780_i2c3),
 669        INGENIC_PIN_GROUP("i2c4-data-e", jz4780_i2c4_e),
 670        INGENIC_PIN_GROUP("i2c4-data-f", jz4780_i2c4_f),
 671        INGENIC_PIN_GROUP("cim-data", jz4770_cim_8bit),
 672        INGENIC_PIN_GROUP("lcd-24bit", jz4770_lcd_24bit),
 673        { "lcd-no-pins", },
 674        INGENIC_PIN_GROUP("pwm0", jz4770_pwm_pwm0),
 675        INGENIC_PIN_GROUP("pwm1", jz4770_pwm_pwm1),
 676        INGENIC_PIN_GROUP("pwm2", jz4770_pwm_pwm2),
 677        INGENIC_PIN_GROUP("pwm3", jz4770_pwm_pwm3),
 678        INGENIC_PIN_GROUP("pwm4", jz4770_pwm_pwm4),
 679        INGENIC_PIN_GROUP("pwm5", jz4770_pwm_pwm5),
 680        INGENIC_PIN_GROUP("pwm6", jz4770_pwm_pwm6),
 681        INGENIC_PIN_GROUP("pwm7", jz4770_pwm_pwm7),
 682};
 683
 684static const char *jz4780_uart2_groups[] = { "uart2-data", "uart2-hwflow", };
 685static const char *jz4780_uart4_groups[] = { "uart4-data", };
 686static const char *jz4780_mmc0_groups[] = {
 687        "mmc0-1bit-a", "mmc0-4bit-a", "mmc0-8bit-a",
 688        "mmc0-1bit-e", "mmc0-4bit-e",
 689};
 690static const char *jz4780_mmc1_groups[] = {
 691        "mmc1-1bit-d", "mmc1-4bit-d", "mmc1-1bit-e", "mmc1-4bit-e",
 692};
 693static const char *jz4780_mmc2_groups[] = {
 694        "mmc2-1bit-b", "mmc2-4bit-b", "mmc2-1bit-e", "mmc2-4bit-e",
 695};
 696static const char *jz4780_nemc_groups[] = {
 697        "nemc-data", "nemc-cle-ale", "nemc-addr",
 698        "nemc-rd-we", "nemc-frd-fwe", "nemc-wait",
 699};
 700static const char *jz4780_i2c3_groups[] = { "i2c3-data", };
 701static const char *jz4780_i2c4_groups[] = { "i2c4-data-e", "i2c4-data-f", };
 702static const char *jz4780_cim_groups[] = { "cim-data", };
 703
 704static const struct function_desc jz4780_functions[] = {
 705        { "uart0", jz4770_uart0_groups, ARRAY_SIZE(jz4770_uart0_groups), },
 706        { "uart1", jz4770_uart1_groups, ARRAY_SIZE(jz4770_uart1_groups), },
 707        { "uart2", jz4780_uart2_groups, ARRAY_SIZE(jz4780_uart2_groups), },
 708        { "uart3", jz4770_uart3_groups, ARRAY_SIZE(jz4770_uart3_groups), },
 709        { "uart4", jz4780_uart4_groups, ARRAY_SIZE(jz4780_uart4_groups), },
 710        { "mmc0", jz4780_mmc0_groups, ARRAY_SIZE(jz4780_mmc0_groups), },
 711        { "mmc1", jz4780_mmc1_groups, ARRAY_SIZE(jz4780_mmc1_groups), },
 712        { "mmc2", jz4780_mmc2_groups, ARRAY_SIZE(jz4780_mmc2_groups), },
 713        { "nemc", jz4780_nemc_groups, ARRAY_SIZE(jz4780_nemc_groups), },
 714        { "nemc-cs1", jz4770_cs1_groups, ARRAY_SIZE(jz4770_cs1_groups), },
 715        { "nemc-cs2", jz4770_cs2_groups, ARRAY_SIZE(jz4770_cs2_groups), },
 716        { "nemc-cs3", jz4770_cs3_groups, ARRAY_SIZE(jz4770_cs3_groups), },
 717        { "nemc-cs4", jz4770_cs4_groups, ARRAY_SIZE(jz4770_cs4_groups), },
 718        { "nemc-cs5", jz4770_cs5_groups, ARRAY_SIZE(jz4770_cs5_groups), },
 719        { "nemc-cs6", jz4770_cs6_groups, ARRAY_SIZE(jz4770_cs6_groups), },
 720        { "i2c0", jz4770_i2c0_groups, ARRAY_SIZE(jz4770_i2c0_groups), },
 721        { "i2c1", jz4770_i2c1_groups, ARRAY_SIZE(jz4770_i2c1_groups), },
 722        { "i2c2", jz4770_i2c2_groups, ARRAY_SIZE(jz4770_i2c2_groups), },
 723        { "i2c3", jz4780_i2c3_groups, ARRAY_SIZE(jz4780_i2c3_groups), },
 724        { "i2c4", jz4780_i2c4_groups, ARRAY_SIZE(jz4780_i2c4_groups), },
 725        { "cim", jz4780_cim_groups, ARRAY_SIZE(jz4780_cim_groups), },
 726        { "lcd", jz4770_lcd_groups, ARRAY_SIZE(jz4770_lcd_groups), },
 727        { "pwm0", jz4770_pwm0_groups, ARRAY_SIZE(jz4770_pwm0_groups), },
 728        { "pwm1", jz4770_pwm1_groups, ARRAY_SIZE(jz4770_pwm1_groups), },
 729        { "pwm2", jz4770_pwm2_groups, ARRAY_SIZE(jz4770_pwm2_groups), },
 730        { "pwm3", jz4770_pwm3_groups, ARRAY_SIZE(jz4770_pwm3_groups), },
 731        { "pwm4", jz4770_pwm4_groups, ARRAY_SIZE(jz4770_pwm4_groups), },
 732        { "pwm5", jz4770_pwm5_groups, ARRAY_SIZE(jz4770_pwm5_groups), },
 733        { "pwm6", jz4770_pwm6_groups, ARRAY_SIZE(jz4770_pwm6_groups), },
 734        { "pwm7", jz4770_pwm7_groups, ARRAY_SIZE(jz4770_pwm7_groups), },
 735};
 736
 737static const struct ingenic_chip_info jz4780_chip_info = {
 738        .num_chips = 6,
 739        .groups = jz4780_groups,
 740        .num_groups = ARRAY_SIZE(jz4780_groups),
 741        .functions = jz4780_functions,
 742        .num_functions = ARRAY_SIZE(jz4780_functions),
 743        .pull_ups = jz4770_pull_ups,
 744        .pull_downs = jz4770_pull_downs,
 745};
 746
 747static u32 ingenic_gpio_read_reg(struct ingenic_gpio_chip *jzgc, u8 reg)
 748{
 749        unsigned int val;
 750
 751        regmap_read(jzgc->jzpc->map, jzgc->reg_base + reg, &val);
 752
 753        return (u32) val;
 754}
 755
 756static void ingenic_gpio_set_bit(struct ingenic_gpio_chip *jzgc,
 757                u8 reg, u8 offset, bool set)
 758{
 759        if (set)
 760                reg = REG_SET(reg);
 761        else
 762                reg = REG_CLEAR(reg);
 763
 764        regmap_write(jzgc->jzpc->map, jzgc->reg_base + reg, BIT(offset));
 765}
 766
 767static inline bool ingenic_gpio_get_value(struct ingenic_gpio_chip *jzgc,
 768                                          u8 offset)
 769{
 770        unsigned int val = ingenic_gpio_read_reg(jzgc, GPIO_PIN);
 771
 772        return !!(val & BIT(offset));
 773}
 774
 775static void ingenic_gpio_set_value(struct ingenic_gpio_chip *jzgc,
 776                                   u8 offset, int value)
 777{
 778        if (jzgc->jzpc->version >= ID_JZ4770)
 779                ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_PAT0, offset, !!value);
 780        else
 781                ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_DATA, offset, !!value);
 782}
 783
 784static void irq_set_type(struct ingenic_gpio_chip *jzgc,
 785                u8 offset, unsigned int type)
 786{
 787        u8 reg1, reg2;
 788
 789        if (jzgc->jzpc->version >= ID_JZ4770) {
 790                reg1 = JZ4770_GPIO_PAT1;
 791                reg2 = JZ4770_GPIO_PAT0;
 792        } else {
 793                reg1 = JZ4740_GPIO_TRIG;
 794                reg2 = JZ4740_GPIO_DIR;
 795        }
 796
 797        switch (type) {
 798        case IRQ_TYPE_EDGE_RISING:
 799                ingenic_gpio_set_bit(jzgc, reg2, offset, true);
 800                ingenic_gpio_set_bit(jzgc, reg1, offset, true);
 801                break;
 802        case IRQ_TYPE_EDGE_FALLING:
 803                ingenic_gpio_set_bit(jzgc, reg2, offset, false);
 804                ingenic_gpio_set_bit(jzgc, reg1, offset, true);
 805                break;
 806        case IRQ_TYPE_LEVEL_HIGH:
 807                ingenic_gpio_set_bit(jzgc, reg2, offset, true);
 808                ingenic_gpio_set_bit(jzgc, reg1, offset, false);
 809                break;
 810        case IRQ_TYPE_LEVEL_LOW:
 811        default:
 812                ingenic_gpio_set_bit(jzgc, reg2, offset, false);
 813                ingenic_gpio_set_bit(jzgc, reg1, offset, false);
 814                break;
 815        }
 816}
 817
 818static void ingenic_gpio_irq_mask(struct irq_data *irqd)
 819{
 820        struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
 821        struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
 822
 823        ingenic_gpio_set_bit(jzgc, GPIO_MSK, irqd->hwirq, true);
 824}
 825
 826static void ingenic_gpio_irq_unmask(struct irq_data *irqd)
 827{
 828        struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
 829        struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
 830
 831        ingenic_gpio_set_bit(jzgc, GPIO_MSK, irqd->hwirq, false);
 832}
 833
 834static void ingenic_gpio_irq_enable(struct irq_data *irqd)
 835{
 836        struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
 837        struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
 838        int irq = irqd->hwirq;
 839
 840        if (jzgc->jzpc->version >= ID_JZ4770)
 841                ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_INT, irq, true);
 842        else
 843                ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, true);
 844
 845        ingenic_gpio_irq_unmask(irqd);
 846}
 847
 848static void ingenic_gpio_irq_disable(struct irq_data *irqd)
 849{
 850        struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
 851        struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
 852        int irq = irqd->hwirq;
 853
 854        ingenic_gpio_irq_mask(irqd);
 855
 856        if (jzgc->jzpc->version >= ID_JZ4770)
 857                ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_INT, irq, false);
 858        else
 859                ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, false);
 860}
 861
 862static void ingenic_gpio_irq_ack(struct irq_data *irqd)
 863{
 864        struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
 865        struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
 866        int irq = irqd->hwirq;
 867        bool high;
 868
 869        if (irqd_get_trigger_type(irqd) == IRQ_TYPE_EDGE_BOTH) {
 870                /*
 871                 * Switch to an interrupt for the opposite edge to the one that
 872                 * triggered the interrupt being ACKed.
 873                 */
 874                high = ingenic_gpio_get_value(jzgc, irq);
 875                if (high)
 876                        irq_set_type(jzgc, irq, IRQ_TYPE_EDGE_FALLING);
 877                else
 878                        irq_set_type(jzgc, irq, IRQ_TYPE_EDGE_RISING);
 879        }
 880
 881        if (jzgc->jzpc->version >= ID_JZ4770)
 882                ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_FLAG, irq, false);
 883        else
 884                ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_DATA, irq, true);
 885}
 886
 887static int ingenic_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
 888{
 889        struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
 890        struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
 891
 892        switch (type) {
 893        case IRQ_TYPE_EDGE_BOTH:
 894        case IRQ_TYPE_EDGE_RISING:
 895        case IRQ_TYPE_EDGE_FALLING:
 896                irq_set_handler_locked(irqd, handle_edge_irq);
 897                break;
 898        case IRQ_TYPE_LEVEL_HIGH:
 899        case IRQ_TYPE_LEVEL_LOW:
 900                irq_set_handler_locked(irqd, handle_level_irq);
 901                break;
 902        default:
 903                irq_set_handler_locked(irqd, handle_bad_irq);
 904        }
 905
 906        if (type == IRQ_TYPE_EDGE_BOTH) {
 907                /*
 908                 * The hardware does not support interrupts on both edges. The
 909                 * best we can do is to set up a single-edge interrupt and then
 910                 * switch to the opposing edge when ACKing the interrupt.
 911                 */
 912                bool high = ingenic_gpio_get_value(jzgc, irqd->hwirq);
 913
 914                type = high ? IRQ_TYPE_EDGE_FALLING : IRQ_TYPE_EDGE_RISING;
 915        }
 916
 917        irq_set_type(jzgc, irqd->hwirq, type);
 918        return 0;
 919}
 920
 921static int ingenic_gpio_irq_set_wake(struct irq_data *irqd, unsigned int on)
 922{
 923        struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
 924        struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
 925
 926        return irq_set_irq_wake(jzgc->irq, on);
 927}
 928
 929static void ingenic_gpio_irq_handler(struct irq_desc *desc)
 930{
 931        struct gpio_chip *gc = irq_desc_get_handler_data(desc);
 932        struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
 933        struct irq_chip *irq_chip = irq_data_get_irq_chip(&desc->irq_data);
 934        unsigned long flag, i;
 935
 936        chained_irq_enter(irq_chip, desc);
 937
 938        if (jzgc->jzpc->version >= ID_JZ4770)
 939                flag = ingenic_gpio_read_reg(jzgc, JZ4770_GPIO_FLAG);
 940        else
 941                flag = ingenic_gpio_read_reg(jzgc, JZ4740_GPIO_FLAG);
 942
 943        for_each_set_bit(i, &flag, 32)
 944                generic_handle_irq(irq_linear_revmap(gc->irq.domain, i));
 945        chained_irq_exit(irq_chip, desc);
 946}
 947
 948static void ingenic_gpio_set(struct gpio_chip *gc,
 949                unsigned int offset, int value)
 950{
 951        struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
 952
 953        ingenic_gpio_set_value(jzgc, offset, value);
 954}
 955
 956static int ingenic_gpio_get(struct gpio_chip *gc, unsigned int offset)
 957{
 958        struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
 959
 960        return (int) ingenic_gpio_get_value(jzgc, offset);
 961}
 962
 963static int ingenic_gpio_direction_input(struct gpio_chip *gc,
 964                unsigned int offset)
 965{
 966        return pinctrl_gpio_direction_input(gc->base + offset);
 967}
 968
 969static int ingenic_gpio_direction_output(struct gpio_chip *gc,
 970                unsigned int offset, int value)
 971{
 972        ingenic_gpio_set(gc, offset, value);
 973        return pinctrl_gpio_direction_output(gc->base + offset);
 974}
 975
 976static inline void ingenic_config_pin(struct ingenic_pinctrl *jzpc,
 977                unsigned int pin, u8 reg, bool set)
 978{
 979        unsigned int idx = pin % PINS_PER_GPIO_CHIP;
 980        unsigned int offt = pin / PINS_PER_GPIO_CHIP;
 981
 982        regmap_write(jzpc->map, offt * 0x100 +
 983                        (set ? REG_SET(reg) : REG_CLEAR(reg)), BIT(idx));
 984}
 985
 986static inline bool ingenic_get_pin_config(struct ingenic_pinctrl *jzpc,
 987                unsigned int pin, u8 reg)
 988{
 989        unsigned int idx = pin % PINS_PER_GPIO_CHIP;
 990        unsigned int offt = pin / PINS_PER_GPIO_CHIP;
 991        unsigned int val;
 992
 993        regmap_read(jzpc->map, offt * 0x100 + reg, &val);
 994
 995        return val & BIT(idx);
 996}
 997
 998static int ingenic_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
 999{
1000        struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
1001        struct ingenic_pinctrl *jzpc = jzgc->jzpc;
1002        unsigned int pin = gc->base + offset;
1003
1004        if (jzpc->version >= ID_JZ4770)
1005                return ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_PAT1);
1006
1007        if (ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_SELECT))
1008                return true;
1009
1010        return !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_DIR);
1011}
1012
1013static const struct pinctrl_ops ingenic_pctlops = {
1014        .get_groups_count = pinctrl_generic_get_group_count,
1015        .get_group_name = pinctrl_generic_get_group_name,
1016        .get_group_pins = pinctrl_generic_get_group_pins,
1017        .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
1018        .dt_free_map = pinconf_generic_dt_free_map,
1019};
1020
1021static int ingenic_pinmux_set_pin_fn(struct ingenic_pinctrl *jzpc,
1022                int pin, int func)
1023{
1024        unsigned int idx = pin % PINS_PER_GPIO_CHIP;
1025        unsigned int offt = pin / PINS_PER_GPIO_CHIP;
1026
1027        dev_dbg(jzpc->dev, "set pin P%c%u to function %u\n",
1028                        'A' + offt, idx, func);
1029
1030        if (jzpc->version >= ID_JZ4770) {
1031                ingenic_config_pin(jzpc, pin, JZ4770_GPIO_INT, false);
1032                ingenic_config_pin(jzpc, pin, GPIO_MSK, false);
1033                ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, func & 0x2);
1034                ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT0, func & 0x1);
1035        } else {
1036                ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, true);
1037                ingenic_config_pin(jzpc, pin, JZ4740_GPIO_TRIG, func & 0x2);
1038                ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, func > 0);
1039        }
1040
1041        return 0;
1042}
1043
1044static int ingenic_pinmux_set_mux(struct pinctrl_dev *pctldev,
1045                unsigned int selector, unsigned int group)
1046{
1047        struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
1048        struct function_desc *func;
1049        struct group_desc *grp;
1050        unsigned int i;
1051
1052        func = pinmux_generic_get_function(pctldev, selector);
1053        if (!func)
1054                return -EINVAL;
1055
1056        grp = pinctrl_generic_get_group(pctldev, group);
1057        if (!grp)
1058                return -EINVAL;
1059
1060        dev_dbg(pctldev->dev, "enable function %s group %s\n",
1061                func->name, grp->name);
1062
1063        for (i = 0; i < grp->num_pins; i++) {
1064                int *pin_modes = grp->data;
1065
1066                ingenic_pinmux_set_pin_fn(jzpc, grp->pins[i], pin_modes[i]);
1067        }
1068
1069        return 0;
1070}
1071
1072static int ingenic_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
1073                struct pinctrl_gpio_range *range,
1074                unsigned int pin, bool input)
1075{
1076        struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
1077        unsigned int idx = pin % PINS_PER_GPIO_CHIP;
1078        unsigned int offt = pin / PINS_PER_GPIO_CHIP;
1079
1080        dev_dbg(pctldev->dev, "set pin P%c%u to %sput\n",
1081                        'A' + offt, idx, input ? "in" : "out");
1082
1083        if (jzpc->version >= ID_JZ4770) {
1084                ingenic_config_pin(jzpc, pin, JZ4770_GPIO_INT, false);
1085                ingenic_config_pin(jzpc, pin, GPIO_MSK, true);
1086                ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, input);
1087        } else {
1088                ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, false);
1089                ingenic_config_pin(jzpc, pin, JZ4740_GPIO_DIR, !input);
1090                ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, false);
1091        }
1092
1093        return 0;
1094}
1095
1096static const struct pinmux_ops ingenic_pmxops = {
1097        .get_functions_count = pinmux_generic_get_function_count,
1098        .get_function_name = pinmux_generic_get_function_name,
1099        .get_function_groups = pinmux_generic_get_function_groups,
1100        .set_mux = ingenic_pinmux_set_mux,
1101        .gpio_set_direction = ingenic_pinmux_gpio_set_direction,
1102};
1103
1104static int ingenic_pinconf_get(struct pinctrl_dev *pctldev,
1105                unsigned int pin, unsigned long *config)
1106{
1107        struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
1108        enum pin_config_param param = pinconf_to_config_param(*config);
1109        unsigned int idx = pin % PINS_PER_GPIO_CHIP;
1110        unsigned int offt = pin / PINS_PER_GPIO_CHIP;
1111        bool pull;
1112
1113        if (jzpc->version >= ID_JZ4770)
1114                pull = !ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_PEN);
1115        else
1116                pull = !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_PULL_DIS);
1117
1118        switch (param) {
1119        case PIN_CONFIG_BIAS_DISABLE:
1120                if (pull)
1121                        return -EINVAL;
1122                break;
1123
1124        case PIN_CONFIG_BIAS_PULL_UP:
1125                if (!pull || !(jzpc->info->pull_ups[offt] & BIT(idx)))
1126                        return -EINVAL;
1127                break;
1128
1129        case PIN_CONFIG_BIAS_PULL_DOWN:
1130                if (!pull || !(jzpc->info->pull_downs[offt] & BIT(idx)))
1131                        return -EINVAL;
1132                break;
1133
1134        default:
1135                return -ENOTSUPP;
1136        }
1137
1138        *config = pinconf_to_config_packed(param, 1);
1139        return 0;
1140}
1141
1142static void ingenic_set_bias(struct ingenic_pinctrl *jzpc,
1143                unsigned int pin, bool enabled)
1144{
1145        if (jzpc->version >= ID_JZ4770)
1146                ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PEN, !enabled);
1147        else
1148                ingenic_config_pin(jzpc, pin, JZ4740_GPIO_PULL_DIS, !enabled);
1149}
1150
1151static int ingenic_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
1152                unsigned long *configs, unsigned int num_configs)
1153{
1154        struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
1155        unsigned int idx = pin % PINS_PER_GPIO_CHIP;
1156        unsigned int offt = pin / PINS_PER_GPIO_CHIP;
1157        unsigned int cfg;
1158
1159        for (cfg = 0; cfg < num_configs; cfg++) {
1160                switch (pinconf_to_config_param(configs[cfg])) {
1161                case PIN_CONFIG_BIAS_DISABLE:
1162                case PIN_CONFIG_BIAS_PULL_UP:
1163                case PIN_CONFIG_BIAS_PULL_DOWN:
1164                        continue;
1165                default:
1166                        return -ENOTSUPP;
1167                }
1168        }
1169
1170        for (cfg = 0; cfg < num_configs; cfg++) {
1171                switch (pinconf_to_config_param(configs[cfg])) {
1172                case PIN_CONFIG_BIAS_DISABLE:
1173                        dev_dbg(jzpc->dev, "disable pull-over for pin P%c%u\n",
1174                                        'A' + offt, idx);
1175                        ingenic_set_bias(jzpc, pin, false);
1176                        break;
1177
1178                case PIN_CONFIG_BIAS_PULL_UP:
1179                        if (!(jzpc->info->pull_ups[offt] & BIT(idx)))
1180                                return -EINVAL;
1181                        dev_dbg(jzpc->dev, "set pull-up for pin P%c%u\n",
1182                                        'A' + offt, idx);
1183                        ingenic_set_bias(jzpc, pin, true);
1184                        break;
1185
1186                case PIN_CONFIG_BIAS_PULL_DOWN:
1187                        if (!(jzpc->info->pull_downs[offt] & BIT(idx)))
1188                                return -EINVAL;
1189                        dev_dbg(jzpc->dev, "set pull-down for pin P%c%u\n",
1190                                        'A' + offt, idx);
1191                        ingenic_set_bias(jzpc, pin, true);
1192                        break;
1193
1194                default:
1195                        unreachable();
1196                }
1197        }
1198
1199        return 0;
1200}
1201
1202static int ingenic_pinconf_group_get(struct pinctrl_dev *pctldev,
1203                unsigned int group, unsigned long *config)
1204{
1205        const unsigned int *pins;
1206        unsigned int i, npins, old = 0;
1207        int ret;
1208
1209        ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
1210        if (ret)
1211                return ret;
1212
1213        for (i = 0; i < npins; i++) {
1214                if (ingenic_pinconf_get(pctldev, pins[i], config))
1215                        return -ENOTSUPP;
1216
1217                /* configs do not match between two pins */
1218                if (i && (old != *config))
1219                        return -ENOTSUPP;
1220
1221                old = *config;
1222        }
1223
1224        return 0;
1225}
1226
1227static int ingenic_pinconf_group_set(struct pinctrl_dev *pctldev,
1228                unsigned int group, unsigned long *configs,
1229                unsigned int num_configs)
1230{
1231        const unsigned int *pins;
1232        unsigned int i, npins;
1233        int ret;
1234
1235        ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
1236        if (ret)
1237                return ret;
1238
1239        for (i = 0; i < npins; i++) {
1240                ret = ingenic_pinconf_set(pctldev,
1241                                pins[i], configs, num_configs);
1242                if (ret)
1243                        return ret;
1244        }
1245
1246        return 0;
1247}
1248
1249static const struct pinconf_ops ingenic_confops = {
1250        .is_generic = true,
1251        .pin_config_get = ingenic_pinconf_get,
1252        .pin_config_set = ingenic_pinconf_set,
1253        .pin_config_group_get = ingenic_pinconf_group_get,
1254        .pin_config_group_set = ingenic_pinconf_group_set,
1255};
1256
1257static const struct regmap_config ingenic_pinctrl_regmap_config = {
1258        .reg_bits = 32,
1259        .val_bits = 32,
1260        .reg_stride = 4,
1261};
1262
1263static const struct of_device_id ingenic_pinctrl_of_match[] = {
1264        { .compatible = "ingenic,jz4740-pinctrl", .data = (void *) ID_JZ4740 },
1265        { .compatible = "ingenic,jz4725b-pinctrl", .data = (void *)ID_JZ4725B },
1266        { .compatible = "ingenic,jz4770-pinctrl", .data = (void *) ID_JZ4770 },
1267        { .compatible = "ingenic,jz4780-pinctrl", .data = (void *) ID_JZ4780 },
1268        {},
1269};
1270
1271static const struct of_device_id ingenic_gpio_of_match[] __initconst = {
1272        { .compatible = "ingenic,jz4740-gpio", },
1273        { .compatible = "ingenic,jz4770-gpio", },
1274        { .compatible = "ingenic,jz4780-gpio", },
1275        {},
1276};
1277
1278static int __init ingenic_gpio_probe(struct ingenic_pinctrl *jzpc,
1279                                     struct device_node *node)
1280{
1281        struct ingenic_gpio_chip *jzgc;
1282        struct device *dev = jzpc->dev;
1283        unsigned int bank;
1284        int err;
1285
1286        err = of_property_read_u32(node, "reg", &bank);
1287        if (err) {
1288                dev_err(dev, "Cannot read \"reg\" property: %i\n", err);
1289                return err;
1290        }
1291
1292        jzgc = devm_kzalloc(dev, sizeof(*jzgc), GFP_KERNEL);
1293        if (!jzgc)
1294                return -ENOMEM;
1295
1296        jzgc->jzpc = jzpc;
1297        jzgc->reg_base = bank * 0x100;
1298
1299        jzgc->gc.label = devm_kasprintf(dev, GFP_KERNEL, "GPIO%c", 'A' + bank);
1300        if (!jzgc->gc.label)
1301                return -ENOMEM;
1302
1303        /* DO NOT EXPAND THIS: FOR BACKWARD GPIO NUMBERSPACE COMPATIBIBILITY
1304         * ONLY: WORK TO TRANSITION CONSUMERS TO USE THE GPIO DESCRIPTOR API IN
1305         * <linux/gpio/consumer.h> INSTEAD.
1306         */
1307        jzgc->gc.base = bank * 32;
1308
1309        jzgc->gc.ngpio = 32;
1310        jzgc->gc.parent = dev;
1311        jzgc->gc.of_node = node;
1312        jzgc->gc.owner = THIS_MODULE;
1313
1314        jzgc->gc.set = ingenic_gpio_set;
1315        jzgc->gc.get = ingenic_gpio_get;
1316        jzgc->gc.direction_input = ingenic_gpio_direction_input;
1317        jzgc->gc.direction_output = ingenic_gpio_direction_output;
1318        jzgc->gc.get_direction = ingenic_gpio_get_direction;
1319
1320        if (of_property_read_bool(node, "gpio-ranges")) {
1321                jzgc->gc.request = gpiochip_generic_request;
1322                jzgc->gc.free = gpiochip_generic_free;
1323        }
1324
1325        err = devm_gpiochip_add_data(dev, &jzgc->gc, jzgc);
1326        if (err)
1327                return err;
1328
1329        jzgc->irq = irq_of_parse_and_map(node, 0);
1330        if (!jzgc->irq)
1331                return -EINVAL;
1332
1333        jzgc->irq_chip.name = jzgc->gc.label;
1334        jzgc->irq_chip.irq_enable = ingenic_gpio_irq_enable;
1335        jzgc->irq_chip.irq_disable = ingenic_gpio_irq_disable;
1336        jzgc->irq_chip.irq_unmask = ingenic_gpio_irq_unmask;
1337        jzgc->irq_chip.irq_mask = ingenic_gpio_irq_mask;
1338        jzgc->irq_chip.irq_ack = ingenic_gpio_irq_ack;
1339        jzgc->irq_chip.irq_set_type = ingenic_gpio_irq_set_type;
1340        jzgc->irq_chip.irq_set_wake = ingenic_gpio_irq_set_wake;
1341        jzgc->irq_chip.flags = IRQCHIP_MASK_ON_SUSPEND;
1342
1343        err = gpiochip_irqchip_add(&jzgc->gc, &jzgc->irq_chip, 0,
1344                        handle_level_irq, IRQ_TYPE_NONE);
1345        if (err)
1346                return err;
1347
1348        gpiochip_set_chained_irqchip(&jzgc->gc, &jzgc->irq_chip,
1349                        jzgc->irq, ingenic_gpio_irq_handler);
1350        return 0;
1351}
1352
1353static int __init ingenic_pinctrl_probe(struct platform_device *pdev)
1354{
1355        struct device *dev = &pdev->dev;
1356        struct ingenic_pinctrl *jzpc;
1357        struct pinctrl_desc *pctl_desc;
1358        void __iomem *base;
1359        const struct platform_device_id *id = platform_get_device_id(pdev);
1360        const struct of_device_id *of_id = of_match_device(
1361                        ingenic_pinctrl_of_match, dev);
1362        const struct ingenic_chip_info *chip_info;
1363        struct device_node *node;
1364        unsigned int i;
1365        int err;
1366
1367        jzpc = devm_kzalloc(dev, sizeof(*jzpc), GFP_KERNEL);
1368        if (!jzpc)
1369                return -ENOMEM;
1370
1371        base = devm_ioremap_resource(dev,
1372                        platform_get_resource(pdev, IORESOURCE_MEM, 0));
1373        if (IS_ERR(base))
1374                return PTR_ERR(base);
1375
1376        jzpc->map = devm_regmap_init_mmio(dev, base,
1377                        &ingenic_pinctrl_regmap_config);
1378        if (IS_ERR(jzpc->map)) {
1379                dev_err(dev, "Failed to create regmap\n");
1380                return PTR_ERR(jzpc->map);
1381        }
1382
1383        jzpc->dev = dev;
1384
1385        if (of_id)
1386                jzpc->version = (enum jz_version)of_id->data;
1387        else
1388                jzpc->version = (enum jz_version)id->driver_data;
1389
1390        if (jzpc->version >= ID_JZ4780)
1391                chip_info = &jz4780_chip_info;
1392        else if (jzpc->version >= ID_JZ4770)
1393                chip_info = &jz4770_chip_info;
1394        else if (jzpc->version >= ID_JZ4725B)
1395                chip_info = &jz4725b_chip_info;
1396        else
1397                chip_info = &jz4740_chip_info;
1398        jzpc->info = chip_info;
1399
1400        pctl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctl_desc), GFP_KERNEL);
1401        if (!pctl_desc)
1402                return -ENOMEM;
1403
1404        /* fill in pinctrl_desc structure */
1405        pctl_desc->name = dev_name(dev);
1406        pctl_desc->owner = THIS_MODULE;
1407        pctl_desc->pctlops = &ingenic_pctlops;
1408        pctl_desc->pmxops = &ingenic_pmxops;
1409        pctl_desc->confops = &ingenic_confops;
1410        pctl_desc->npins = chip_info->num_chips * PINS_PER_GPIO_CHIP;
1411        pctl_desc->pins = jzpc->pdesc = devm_kcalloc(&pdev->dev,
1412                        pctl_desc->npins, sizeof(*jzpc->pdesc), GFP_KERNEL);
1413        if (!jzpc->pdesc)
1414                return -ENOMEM;
1415
1416        for (i = 0; i < pctl_desc->npins; i++) {
1417                jzpc->pdesc[i].number = i;
1418                jzpc->pdesc[i].name = kasprintf(GFP_KERNEL, "P%c%d",
1419                                                'A' + (i / PINS_PER_GPIO_CHIP),
1420                                                i % PINS_PER_GPIO_CHIP);
1421        }
1422
1423        jzpc->pctl = devm_pinctrl_register(dev, pctl_desc, jzpc);
1424        if (IS_ERR(jzpc->pctl)) {
1425                dev_err(dev, "Failed to register pinctrl\n");
1426                return PTR_ERR(jzpc->pctl);
1427        }
1428
1429        for (i = 0; i < chip_info->num_groups; i++) {
1430                const struct group_desc *group = &chip_info->groups[i];
1431
1432                err = pinctrl_generic_add_group(jzpc->pctl, group->name,
1433                                group->pins, group->num_pins, group->data);
1434                if (err < 0) {
1435                        dev_err(dev, "Failed to register group %s\n",
1436                                        group->name);
1437                        return err;
1438                }
1439        }
1440
1441        for (i = 0; i < chip_info->num_functions; i++) {
1442                const struct function_desc *func = &chip_info->functions[i];
1443
1444                err = pinmux_generic_add_function(jzpc->pctl, func->name,
1445                                func->group_names, func->num_group_names,
1446                                func->data);
1447                if (err < 0) {
1448                        dev_err(dev, "Failed to register function %s\n",
1449                                        func->name);
1450                        return err;
1451                }
1452        }
1453
1454        dev_set_drvdata(dev, jzpc->map);
1455
1456        for_each_child_of_node(dev->of_node, node) {
1457                if (of_match_node(ingenic_gpio_of_match, node)) {
1458                        err = ingenic_gpio_probe(jzpc, node);
1459                        if (err)
1460                                return err;
1461                }
1462        }
1463
1464        return 0;
1465}
1466
1467static const struct platform_device_id ingenic_pinctrl_ids[] = {
1468        { "jz4740-pinctrl", ID_JZ4740 },
1469        { "jz4725b-pinctrl", ID_JZ4725B },
1470        { "jz4770-pinctrl", ID_JZ4770 },
1471        { "jz4780-pinctrl", ID_JZ4780 },
1472        {},
1473};
1474
1475static struct platform_driver ingenic_pinctrl_driver = {
1476        .driver = {
1477                .name = "pinctrl-ingenic",
1478                .of_match_table = of_match_ptr(ingenic_pinctrl_of_match),
1479        },
1480        .id_table = ingenic_pinctrl_ids,
1481};
1482
1483static int __init ingenic_pinctrl_drv_register(void)
1484{
1485        return platform_driver_probe(&ingenic_pinctrl_driver,
1486                                     ingenic_pinctrl_probe);
1487}
1488subsys_initcall(ingenic_pinctrl_drv_register);
1489