linux/drivers/pinctrl/pinctrl-ingenic.c
<<
>>
Prefs
   1/*
   2 * Ingenic SoCs pinctrl driver
   3 *
   4 * Copyright (c) 2017 Paul Cercueil <paul@crapouillou.net>
   5 *
   6 * License terms: GNU General Public License (GPL) version 2
   7 */
   8
   9#include <linux/compiler.h>
  10#include <linux/gpio.h>
  11#include <linux/interrupt.h>
  12#include <linux/io.h>
  13#include <linux/of_device.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 JZ4740_GPIO_DATA        0x10
  28#define JZ4740_GPIO_PULL_DIS    0x30
  29#define JZ4740_GPIO_FUNC        0x40
  30#define JZ4740_GPIO_SELECT      0x50
  31#define JZ4740_GPIO_DIR         0x60
  32#define JZ4740_GPIO_TRIG        0x70
  33#define JZ4740_GPIO_FLAG        0x80
  34
  35#define JZ4770_GPIO_INT         0x10
  36#define JZ4770_GPIO_MSK         0x20
  37#define JZ4770_GPIO_PAT1        0x30
  38#define JZ4770_GPIO_PAT0        0x40
  39#define JZ4770_GPIO_FLAG        0x50
  40#define JZ4770_GPIO_PEN         0x70
  41
  42#define REG_SET(x) ((x) + 0x4)
  43#define REG_CLEAR(x) ((x) + 0x8)
  44
  45#define PINS_PER_GPIO_CHIP 32
  46
  47enum jz_version {
  48        ID_JZ4740,
  49        ID_JZ4770,
  50        ID_JZ4780,
  51};
  52
  53struct ingenic_chip_info {
  54        unsigned int num_chips;
  55
  56        const struct group_desc *groups;
  57        unsigned int num_groups;
  58
  59        const struct function_desc *functions;
  60        unsigned int num_functions;
  61
  62        const u32 *pull_ups, *pull_downs;
  63};
  64
  65struct ingenic_pinctrl {
  66        struct device *dev;
  67        struct regmap *map;
  68        struct pinctrl_dev *pctl;
  69        struct pinctrl_pin_desc *pdesc;
  70        enum jz_version version;
  71
  72        const struct ingenic_chip_info *info;
  73};
  74
  75static const u32 jz4740_pull_ups[4] = {
  76        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
  77};
  78
  79static const u32 jz4740_pull_downs[4] = {
  80        0x00000000, 0x00000000, 0x00000000, 0x00000000,
  81};
  82
  83static int jz4740_mmc_1bit_pins[] = { 0x69, 0x68, 0x6a, };
  84static int jz4740_mmc_4bit_pins[] = { 0x6b, 0x6c, 0x6d, };
  85static int jz4740_uart0_data_pins[] = { 0x7a, 0x79, };
  86static int jz4740_uart0_hwflow_pins[] = { 0x7e, 0x7f, };
  87static int jz4740_uart1_data_pins[] = { 0x7e, 0x7f, };
  88static int jz4740_lcd_8bit_pins[] = {
  89        0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x52, 0x53, 0x54,
  90};
  91static int jz4740_lcd_16bit_pins[] = {
  92        0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x55,
  93};
  94static int jz4740_lcd_18bit_pins[] = { 0x50, 0x51, };
  95static int jz4740_lcd_18bit_tft_pins[] = { 0x56, 0x57, 0x31, 0x32, };
  96static int jz4740_nand_cs1_pins[] = { 0x39, };
  97static int jz4740_nand_cs2_pins[] = { 0x3a, };
  98static int jz4740_nand_cs3_pins[] = { 0x3b, };
  99static int jz4740_nand_cs4_pins[] = { 0x3c, };
 100static int jz4740_pwm_pwm0_pins[] = { 0x77, };
 101static int jz4740_pwm_pwm1_pins[] = { 0x78, };
 102static int jz4740_pwm_pwm2_pins[] = { 0x79, };
 103static int jz4740_pwm_pwm3_pins[] = { 0x7a, };
 104static int jz4740_pwm_pwm4_pins[] = { 0x7b, };
 105static int jz4740_pwm_pwm5_pins[] = { 0x7c, };
 106static int jz4740_pwm_pwm6_pins[] = { 0x7e, };
 107static int jz4740_pwm_pwm7_pins[] = { 0x7f, };
 108
 109static int jz4740_mmc_1bit_funcs[] = { 0, 0, 0, };
 110static int jz4740_mmc_4bit_funcs[] = { 0, 0, 0, };
 111static int jz4740_uart0_data_funcs[] = { 1, 1, };
 112static int jz4740_uart0_hwflow_funcs[] = { 1, 1, };
 113static int jz4740_uart1_data_funcs[] = { 2, 2, };
 114static int jz4740_lcd_8bit_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
 115static int jz4740_lcd_16bit_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, };
 116static int jz4740_lcd_18bit_funcs[] = { 0, 0, };
 117static int jz4740_lcd_18bit_tft_funcs[] = { 0, 0, 0, 0, };
 118static int jz4740_nand_cs1_funcs[] = { 0, };
 119static int jz4740_nand_cs2_funcs[] = { 0, };
 120static int jz4740_nand_cs3_funcs[] = { 0, };
 121static int jz4740_nand_cs4_funcs[] = { 0, };
 122static int jz4740_pwm_pwm0_funcs[] = { 0, };
 123static int jz4740_pwm_pwm1_funcs[] = { 0, };
 124static int jz4740_pwm_pwm2_funcs[] = { 0, };
 125static int jz4740_pwm_pwm3_funcs[] = { 0, };
 126static int jz4740_pwm_pwm4_funcs[] = { 0, };
 127static int jz4740_pwm_pwm5_funcs[] = { 0, };
 128static int jz4740_pwm_pwm6_funcs[] = { 0, };
 129static int jz4740_pwm_pwm7_funcs[] = { 0, };
 130
 131#define INGENIC_PIN_GROUP(name, id)                     \
 132        {                                               \
 133                name,                                   \
 134                id##_pins,                              \
 135                ARRAY_SIZE(id##_pins),                  \
 136                id##_funcs,                             \
 137        }
 138
 139static const struct group_desc jz4740_groups[] = {
 140        INGENIC_PIN_GROUP("mmc-1bit", jz4740_mmc_1bit),
 141        INGENIC_PIN_GROUP("mmc-4bit", jz4740_mmc_4bit),
 142        INGENIC_PIN_GROUP("uart0-data", jz4740_uart0_data),
 143        INGENIC_PIN_GROUP("uart0-hwflow", jz4740_uart0_hwflow),
 144        INGENIC_PIN_GROUP("uart1-data", jz4740_uart1_data),
 145        INGENIC_PIN_GROUP("lcd-8bit", jz4740_lcd_8bit),
 146        INGENIC_PIN_GROUP("lcd-16bit", jz4740_lcd_16bit),
 147        INGENIC_PIN_GROUP("lcd-18bit", jz4740_lcd_18bit),
 148        INGENIC_PIN_GROUP("lcd-18bit-tft", jz4740_lcd_18bit_tft),
 149        { "lcd-no-pins", },
 150        INGENIC_PIN_GROUP("nand-cs1", jz4740_nand_cs1),
 151        INGENIC_PIN_GROUP("nand-cs2", jz4740_nand_cs2),
 152        INGENIC_PIN_GROUP("nand-cs3", jz4740_nand_cs3),
 153        INGENIC_PIN_GROUP("nand-cs4", jz4740_nand_cs4),
 154        INGENIC_PIN_GROUP("pwm0", jz4740_pwm_pwm0),
 155        INGENIC_PIN_GROUP("pwm1", jz4740_pwm_pwm1),
 156        INGENIC_PIN_GROUP("pwm2", jz4740_pwm_pwm2),
 157        INGENIC_PIN_GROUP("pwm3", jz4740_pwm_pwm3),
 158        INGENIC_PIN_GROUP("pwm4", jz4740_pwm_pwm4),
 159        INGENIC_PIN_GROUP("pwm5", jz4740_pwm_pwm5),
 160        INGENIC_PIN_GROUP("pwm6", jz4740_pwm_pwm6),
 161        INGENIC_PIN_GROUP("pwm7", jz4740_pwm_pwm7),
 162};
 163
 164static const char *jz4740_mmc_groups[] = { "mmc-1bit", "mmc-4bit", };
 165static const char *jz4740_uart0_groups[] = { "uart0-data", "uart0-hwflow", };
 166static const char *jz4740_uart1_groups[] = { "uart1-data", };
 167static const char *jz4740_lcd_groups[] = {
 168        "lcd-8bit", "lcd-16bit", "lcd-18bit", "lcd-18bit-tft", "lcd-no-pins",
 169};
 170static const char *jz4740_nand_groups[] = {
 171        "nand-cs1", "nand-cs2", "nand-cs3", "nand-cs4",
 172};
 173static const char *jz4740_pwm0_groups[] = { "pwm0", };
 174static const char *jz4740_pwm1_groups[] = { "pwm1", };
 175static const char *jz4740_pwm2_groups[] = { "pwm2", };
 176static const char *jz4740_pwm3_groups[] = { "pwm3", };
 177static const char *jz4740_pwm4_groups[] = { "pwm4", };
 178static const char *jz4740_pwm5_groups[] = { "pwm5", };
 179static const char *jz4740_pwm6_groups[] = { "pwm6", };
 180static const char *jz4740_pwm7_groups[] = { "pwm7", };
 181
 182static const struct function_desc jz4740_functions[] = {
 183        { "mmc", jz4740_mmc_groups, ARRAY_SIZE(jz4740_mmc_groups), },
 184        { "uart0", jz4740_uart0_groups, ARRAY_SIZE(jz4740_uart0_groups), },
 185        { "uart1", jz4740_uart1_groups, ARRAY_SIZE(jz4740_uart1_groups), },
 186        { "lcd", jz4740_lcd_groups, ARRAY_SIZE(jz4740_lcd_groups), },
 187        { "nand", jz4740_nand_groups, ARRAY_SIZE(jz4740_nand_groups), },
 188        { "pwm0", jz4740_pwm0_groups, ARRAY_SIZE(jz4740_pwm0_groups), },
 189        { "pwm1", jz4740_pwm1_groups, ARRAY_SIZE(jz4740_pwm1_groups), },
 190        { "pwm2", jz4740_pwm2_groups, ARRAY_SIZE(jz4740_pwm2_groups), },
 191        { "pwm3", jz4740_pwm3_groups, ARRAY_SIZE(jz4740_pwm3_groups), },
 192        { "pwm4", jz4740_pwm4_groups, ARRAY_SIZE(jz4740_pwm4_groups), },
 193        { "pwm5", jz4740_pwm5_groups, ARRAY_SIZE(jz4740_pwm5_groups), },
 194        { "pwm6", jz4740_pwm6_groups, ARRAY_SIZE(jz4740_pwm6_groups), },
 195        { "pwm7", jz4740_pwm7_groups, ARRAY_SIZE(jz4740_pwm7_groups), },
 196};
 197
 198static const struct ingenic_chip_info jz4740_chip_info = {
 199        .num_chips = 4,
 200        .groups = jz4740_groups,
 201        .num_groups = ARRAY_SIZE(jz4740_groups),
 202        .functions = jz4740_functions,
 203        .num_functions = ARRAY_SIZE(jz4740_functions),
 204        .pull_ups = jz4740_pull_ups,
 205        .pull_downs = jz4740_pull_downs,
 206};
 207
 208static const u32 jz4770_pull_ups[6] = {
 209        0x3fffffff, 0xfff0030c, 0xffffffff, 0xffff4fff, 0xfffffb7c, 0xffa7f00f,
 210};
 211
 212static const u32 jz4770_pull_downs[6] = {
 213        0x00000000, 0x000f0c03, 0x00000000, 0x0000b000, 0x00000483, 0x00580ff0,
 214};
 215
 216static int jz4770_uart0_data_pins[] = { 0xa0, 0xa3, };
 217static int jz4770_uart0_hwflow_pins[] = { 0xa1, 0xa2, };
 218static int jz4770_uart1_data_pins[] = { 0x7a, 0x7c, };
 219static int jz4770_uart1_hwflow_pins[] = { 0x7b, 0x7d, };
 220static int jz4770_uart2_data_pins[] = { 0x66, 0x67, };
 221static int jz4770_uart2_hwflow_pins[] = { 0x65, 0x64, };
 222static int jz4770_uart3_data_pins[] = { 0x6c, 0x85, };
 223static int jz4770_uart3_hwflow_pins[] = { 0x88, 0x89, };
 224static int jz4770_uart4_data_pins[] = { 0x54, 0x4a, };
 225static int jz4770_mmc0_8bit_a_pins[] = { 0x04, 0x05, 0x06, 0x07, 0x18, };
 226static int jz4770_mmc0_4bit_a_pins[] = { 0x15, 0x16, 0x17, };
 227static int jz4770_mmc0_1bit_a_pins[] = { 0x12, 0x13, 0x14, };
 228static int jz4770_mmc0_4bit_e_pins[] = { 0x95, 0x96, 0x97, };
 229static int jz4770_mmc0_1bit_e_pins[] = { 0x9c, 0x9d, 0x94, };
 230static int jz4770_mmc1_4bit_d_pins[] = { 0x75, 0x76, 0x77, };
 231static int jz4770_mmc1_1bit_d_pins[] = { 0x78, 0x79, 0x74, };
 232static int jz4770_mmc1_4bit_e_pins[] = { 0x95, 0x96, 0x97, };
 233static int jz4770_mmc1_1bit_e_pins[] = { 0x9c, 0x9d, 0x94, };
 234static int jz4770_nemc_data_pins[] = {
 235        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
 236};
 237static int jz4770_nemc_cle_ale_pins[] = { 0x20, 0x21, };
 238static int jz4770_nemc_addr_pins[] = { 0x22, 0x23, 0x24, 0x25, };
 239static int jz4770_nemc_rd_we_pins[] = { 0x10, 0x11, };
 240static int jz4770_nemc_frd_fwe_pins[] = { 0x12, 0x13, };
 241static int jz4770_nemc_cs1_pins[] = { 0x15, };
 242static int jz4770_nemc_cs2_pins[] = { 0x16, };
 243static int jz4770_nemc_cs3_pins[] = { 0x17, };
 244static int jz4770_nemc_cs4_pins[] = { 0x18, };
 245static int jz4770_nemc_cs5_pins[] = { 0x19, };
 246static int jz4770_nemc_cs6_pins[] = { 0x1a, };
 247static int jz4770_i2c0_pins[] = { 0x6e, 0x6f, };
 248static int jz4770_i2c1_pins[] = { 0x8e, 0x8f, };
 249static int jz4770_i2c2_pins[] = { 0xb0, 0xb1, };
 250static int jz4770_i2c3_pins[] = { 0x6a, 0x6b, };
 251static int jz4770_i2c4_e_pins[] = { 0x8c, 0x8d, };
 252static int jz4770_i2c4_f_pins[] = { 0xb9, 0xb8, };
 253static int jz4770_cim_pins[] = {
 254        0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
 255};
 256static int jz4770_lcd_32bit_pins[] = {
 257        0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
 258        0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
 259        0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
 260        0x58, 0x59, 0x51,
 261};
 262static int jz4770_pwm_pwm0_pins[] = { 0x80, };
 263static int jz4770_pwm_pwm1_pins[] = { 0x81, };
 264static int jz4770_pwm_pwm2_pins[] = { 0x82, };
 265static int jz4770_pwm_pwm3_pins[] = { 0x83, };
 266static int jz4770_pwm_pwm4_pins[] = { 0x84, };
 267static int jz4770_pwm_pwm5_pins[] = { 0x85, };
 268static int jz4770_pwm_pwm6_pins[] = { 0x6a, };
 269static int jz4770_pwm_pwm7_pins[] = { 0x6b, };
 270
 271static int jz4770_uart0_data_funcs[] = { 0, 0, };
 272static int jz4770_uart0_hwflow_funcs[] = { 0, 0, };
 273static int jz4770_uart1_data_funcs[] = { 0, 0, };
 274static int jz4770_uart1_hwflow_funcs[] = { 0, 0, };
 275static int jz4770_uart2_data_funcs[] = { 1, 1, };
 276static int jz4770_uart2_hwflow_funcs[] = { 1, 1, };
 277static int jz4770_uart3_data_funcs[] = { 0, 1, };
 278static int jz4770_uart3_hwflow_funcs[] = { 0, 0, };
 279static int jz4770_uart4_data_funcs[] = { 2, 2, };
 280static int jz4770_mmc0_8bit_a_funcs[] = { 1, 1, 1, 1, 1, };
 281static int jz4770_mmc0_4bit_a_funcs[] = { 1, 1, 1, };
 282static int jz4770_mmc0_1bit_a_funcs[] = { 1, 1, 0, };
 283static int jz4770_mmc0_4bit_e_funcs[] = { 0, 0, 0, };
 284static int jz4770_mmc0_1bit_e_funcs[] = { 0, 0, 0, };
 285static int jz4770_mmc1_4bit_d_funcs[] = { 0, 0, 0, };
 286static int jz4770_mmc1_1bit_d_funcs[] = { 0, 0, 0, };
 287static int jz4770_mmc1_4bit_e_funcs[] = { 1, 1, 1, };
 288static int jz4770_mmc1_1bit_e_funcs[] = { 1, 1, 1, };
 289static int jz4770_nemc_data_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, };
 290static int jz4770_nemc_cle_ale_funcs[] = { 0, 0, };
 291static int jz4770_nemc_addr_funcs[] = { 0, 0, 0, 0, };
 292static int jz4770_nemc_rd_we_funcs[] = { 0, 0, };
 293static int jz4770_nemc_frd_fwe_funcs[] = { 0, 0, };
 294static int jz4770_nemc_cs1_funcs[] = { 0, };
 295static int jz4770_nemc_cs2_funcs[] = { 0, };
 296static int jz4770_nemc_cs3_funcs[] = { 0, };
 297static int jz4770_nemc_cs4_funcs[] = { 0, };
 298static int jz4770_nemc_cs5_funcs[] = { 0, };
 299static int jz4770_nemc_cs6_funcs[] = { 0, };
 300static int jz4770_i2c0_funcs[] = { 0, 0, };
 301static int jz4770_i2c1_funcs[] = { 0, 0, };
 302static int jz4770_i2c2_funcs[] = { 2, 2, };
 303static int jz4770_i2c3_funcs[] = { 1, 1, };
 304static int jz4770_i2c4_e_funcs[] = { 1, 1, };
 305static int jz4770_i2c4_f_funcs[] = { 1, 1, };
 306static int jz4770_cim_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
 307static int jz4770_lcd_32bit_funcs[] = {
 308        0, 0, 0, 0, 0, 0, 0, 0,
 309        0, 0, 0, 0, 0, 0, 0, 0,
 310        0, 0, 0,
 311};
 312static int jz4770_pwm_pwm0_funcs[] = { 0, };
 313static int jz4770_pwm_pwm1_funcs[] = { 0, };
 314static int jz4770_pwm_pwm2_funcs[] = { 0, };
 315static int jz4770_pwm_pwm3_funcs[] = { 0, };
 316static int jz4770_pwm_pwm4_funcs[] = { 0, };
 317static int jz4770_pwm_pwm5_funcs[] = { 0, };
 318static int jz4770_pwm_pwm6_funcs[] = { 0, };
 319static int jz4770_pwm_pwm7_funcs[] = { 0, };
 320
 321static const struct group_desc jz4770_groups[] = {
 322        INGENIC_PIN_GROUP("uart0-data", jz4770_uart0_data),
 323        INGENIC_PIN_GROUP("uart0-hwflow", jz4770_uart0_hwflow),
 324        INGENIC_PIN_GROUP("uart1-data", jz4770_uart1_data),
 325        INGENIC_PIN_GROUP("uart1-hwflow", jz4770_uart1_hwflow),
 326        INGENIC_PIN_GROUP("uart2-data", jz4770_uart2_data),
 327        INGENIC_PIN_GROUP("uart2-hwflow", jz4770_uart2_hwflow),
 328        INGENIC_PIN_GROUP("uart3-data", jz4770_uart3_data),
 329        INGENIC_PIN_GROUP("uart3-hwflow", jz4770_uart3_hwflow),
 330        INGENIC_PIN_GROUP("uart4-data", jz4770_uart4_data),
 331        INGENIC_PIN_GROUP("mmc0-8bit-a", jz4770_mmc0_8bit_a),
 332        INGENIC_PIN_GROUP("mmc0-4bit-a", jz4770_mmc0_4bit_a),
 333        INGENIC_PIN_GROUP("mmc0-1bit-a", jz4770_mmc0_1bit_a),
 334        INGENIC_PIN_GROUP("mmc0-4bit-e", jz4770_mmc0_4bit_e),
 335        INGENIC_PIN_GROUP("mmc0-1bit-e", jz4770_mmc0_1bit_e),
 336        INGENIC_PIN_GROUP("mmc1-4bit-d", jz4770_mmc1_4bit_d),
 337        INGENIC_PIN_GROUP("mmc1-1bit-d", jz4770_mmc1_1bit_d),
 338        INGENIC_PIN_GROUP("mmc1-4bit-e", jz4770_mmc1_4bit_e),
 339        INGENIC_PIN_GROUP("mmc1-1bit-e", jz4770_mmc1_1bit_e),
 340        INGENIC_PIN_GROUP("nemc-data", jz4770_nemc_data),
 341        INGENIC_PIN_GROUP("nemc-cle-ale", jz4770_nemc_cle_ale),
 342        INGENIC_PIN_GROUP("nemc-addr", jz4770_nemc_addr),
 343        INGENIC_PIN_GROUP("nemc-rd-we", jz4770_nemc_rd_we),
 344        INGENIC_PIN_GROUP("nemc-frd-fwe", jz4770_nemc_frd_fwe),
 345        INGENIC_PIN_GROUP("nemc-cs1", jz4770_nemc_cs1),
 346        INGENIC_PIN_GROUP("nemc-cs2", jz4770_nemc_cs2),
 347        INGENIC_PIN_GROUP("nemc-cs3", jz4770_nemc_cs3),
 348        INGENIC_PIN_GROUP("nemc-cs4", jz4770_nemc_cs4),
 349        INGENIC_PIN_GROUP("nemc-cs5", jz4770_nemc_cs5),
 350        INGENIC_PIN_GROUP("nemc-cs6", jz4770_nemc_cs6),
 351        INGENIC_PIN_GROUP("i2c0-data", jz4770_i2c0),
 352        INGENIC_PIN_GROUP("i2c1-data", jz4770_i2c1),
 353        INGENIC_PIN_GROUP("i2c2-data", jz4770_i2c2),
 354        INGENIC_PIN_GROUP("i2c3-data", jz4770_i2c3),
 355        INGENIC_PIN_GROUP("i2c4-data-e", jz4770_i2c4_e),
 356        INGENIC_PIN_GROUP("i2c4-data-f", jz4770_i2c4_f),
 357        INGENIC_PIN_GROUP("cim-data", jz4770_cim),
 358        INGENIC_PIN_GROUP("lcd-32bit", jz4770_lcd_32bit),
 359        { "lcd-no-pins", },
 360        INGENIC_PIN_GROUP("pwm0", jz4770_pwm_pwm0),
 361        INGENIC_PIN_GROUP("pwm1", jz4770_pwm_pwm1),
 362        INGENIC_PIN_GROUP("pwm2", jz4770_pwm_pwm2),
 363        INGENIC_PIN_GROUP("pwm3", jz4770_pwm_pwm3),
 364        INGENIC_PIN_GROUP("pwm4", jz4770_pwm_pwm4),
 365        INGENIC_PIN_GROUP("pwm5", jz4770_pwm_pwm5),
 366        INGENIC_PIN_GROUP("pwm6", jz4770_pwm_pwm6),
 367        INGENIC_PIN_GROUP("pwm7", jz4770_pwm_pwm7),
 368};
 369
 370static const char *jz4770_uart0_groups[] = { "uart0-data", "uart0-hwflow", };
 371static const char *jz4770_uart1_groups[] = { "uart1-data", "uart1-hwflow", };
 372static const char *jz4770_uart2_groups[] = { "uart2-data", "uart2-hwflow", };
 373static const char *jz4770_uart3_groups[] = { "uart3-data", "uart3-hwflow", };
 374static const char *jz4770_uart4_groups[] = { "uart4-data", };
 375static const char *jz4770_mmc0_groups[] = {
 376        "mmc0-8bit-a", "mmc0-4bit-a", "mmc0-1bit-a",
 377        "mmc0-1bit-e", "mmc0-4bit-e",
 378};
 379static const char *jz4770_mmc1_groups[] = {
 380        "mmc1-1bit-d", "mmc1-4bit-d", "mmc1-1bit-e", "mmc1-4bit-e",
 381};
 382static const char *jz4770_nemc_groups[] = {
 383        "nemc-data", "nemc-cle-ale", "nemc-addr", "nemc-rd-we", "nemc-frd-fwe",
 384};
 385static const char *jz4770_cs1_groups[] = { "nemc-cs1", };
 386static const char *jz4770_cs6_groups[] = { "nemc-cs6", };
 387static const char *jz4770_i2c0_groups[] = { "i2c0-data", };
 388static const char *jz4770_i2c1_groups[] = { "i2c1-data", };
 389static const char *jz4770_i2c2_groups[] = { "i2c2-data", };
 390static const char *jz4770_i2c3_groups[] = { "i2c3-data", };
 391static const char *jz4770_i2c4_groups[] = { "i2c4-data-e", "i2c4-data-f", };
 392static const char *jz4770_cim_groups[] = { "cim-data", };
 393static const char *jz4770_lcd_groups[] = { "lcd-32bit", "lcd-no-pins", };
 394static const char *jz4770_pwm0_groups[] = { "pwm0", };
 395static const char *jz4770_pwm1_groups[] = { "pwm1", };
 396static const char *jz4770_pwm2_groups[] = { "pwm2", };
 397static const char *jz4770_pwm3_groups[] = { "pwm3", };
 398static const char *jz4770_pwm4_groups[] = { "pwm4", };
 399static const char *jz4770_pwm5_groups[] = { "pwm5", };
 400static const char *jz4770_pwm6_groups[] = { "pwm6", };
 401static const char *jz4770_pwm7_groups[] = { "pwm7", };
 402
 403static const struct function_desc jz4770_functions[] = {
 404        { "uart0", jz4770_uart0_groups, ARRAY_SIZE(jz4770_uart0_groups), },
 405        { "uart1", jz4770_uart1_groups, ARRAY_SIZE(jz4770_uart1_groups), },
 406        { "uart2", jz4770_uart2_groups, ARRAY_SIZE(jz4770_uart2_groups), },
 407        { "uart3", jz4770_uart3_groups, ARRAY_SIZE(jz4770_uart3_groups), },
 408        { "uart4", jz4770_uart4_groups, ARRAY_SIZE(jz4770_uart4_groups), },
 409        { "mmc0", jz4770_mmc0_groups, ARRAY_SIZE(jz4770_mmc0_groups), },
 410        { "mmc1", jz4770_mmc1_groups, ARRAY_SIZE(jz4770_mmc1_groups), },
 411        { "nemc", jz4770_nemc_groups, ARRAY_SIZE(jz4770_nemc_groups), },
 412        { "nemc-cs1", jz4770_cs1_groups, ARRAY_SIZE(jz4770_cs1_groups), },
 413        { "nemc-cs6", jz4770_cs6_groups, ARRAY_SIZE(jz4770_cs6_groups), },
 414        { "i2c0", jz4770_i2c0_groups, ARRAY_SIZE(jz4770_i2c0_groups), },
 415        { "i2c1", jz4770_i2c1_groups, ARRAY_SIZE(jz4770_i2c1_groups), },
 416        { "i2c2", jz4770_i2c2_groups, ARRAY_SIZE(jz4770_i2c2_groups), },
 417        { "i2c3", jz4770_i2c3_groups, ARRAY_SIZE(jz4770_i2c3_groups), },
 418        { "i2c4", jz4770_i2c4_groups, ARRAY_SIZE(jz4770_i2c4_groups), },
 419        { "cim", jz4770_cim_groups, ARRAY_SIZE(jz4770_cim_groups), },
 420        { "lcd", jz4770_lcd_groups, ARRAY_SIZE(jz4770_lcd_groups), },
 421        { "pwm0", jz4770_pwm0_groups, ARRAY_SIZE(jz4770_pwm0_groups), },
 422        { "pwm1", jz4770_pwm1_groups, ARRAY_SIZE(jz4770_pwm1_groups), },
 423        { "pwm2", jz4770_pwm2_groups, ARRAY_SIZE(jz4770_pwm2_groups), },
 424        { "pwm3", jz4770_pwm3_groups, ARRAY_SIZE(jz4770_pwm3_groups), },
 425        { "pwm4", jz4770_pwm4_groups, ARRAY_SIZE(jz4770_pwm4_groups), },
 426        { "pwm5", jz4770_pwm5_groups, ARRAY_SIZE(jz4770_pwm5_groups), },
 427        { "pwm6", jz4770_pwm6_groups, ARRAY_SIZE(jz4770_pwm6_groups), },
 428        { "pwm7", jz4770_pwm7_groups, ARRAY_SIZE(jz4770_pwm7_groups), },
 429};
 430
 431static const struct ingenic_chip_info jz4770_chip_info = {
 432        .num_chips = 6,
 433        .groups = jz4770_groups,
 434        .num_groups = ARRAY_SIZE(jz4770_groups),
 435        .functions = jz4770_functions,
 436        .num_functions = ARRAY_SIZE(jz4770_functions),
 437        .pull_ups = jz4770_pull_ups,
 438        .pull_downs = jz4770_pull_downs,
 439};
 440
 441static inline void ingenic_config_pin(struct ingenic_pinctrl *jzpc,
 442                unsigned int pin, u8 reg, bool set)
 443{
 444        unsigned int idx = pin % PINS_PER_GPIO_CHIP;
 445        unsigned int offt = pin / PINS_PER_GPIO_CHIP;
 446
 447        regmap_write(jzpc->map, offt * 0x100 +
 448                        (set ? REG_SET(reg) : REG_CLEAR(reg)), BIT(idx));
 449}
 450
 451static inline bool ingenic_get_pin_config(struct ingenic_pinctrl *jzpc,
 452                unsigned int pin, u8 reg)
 453{
 454        unsigned int idx = pin % PINS_PER_GPIO_CHIP;
 455        unsigned int offt = pin / PINS_PER_GPIO_CHIP;
 456        unsigned int val;
 457
 458        regmap_read(jzpc->map, offt * 0x100 + reg, &val);
 459
 460        return val & BIT(idx);
 461}
 462
 463static const struct pinctrl_ops ingenic_pctlops = {
 464        .get_groups_count = pinctrl_generic_get_group_count,
 465        .get_group_name = pinctrl_generic_get_group_name,
 466        .get_group_pins = pinctrl_generic_get_group_pins,
 467        .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
 468        .dt_free_map = pinconf_generic_dt_free_map,
 469};
 470
 471static int ingenic_pinmux_set_pin_fn(struct ingenic_pinctrl *jzpc,
 472                int pin, int func)
 473{
 474        unsigned int idx = pin % PINS_PER_GPIO_CHIP;
 475        unsigned int offt = pin / PINS_PER_GPIO_CHIP;
 476
 477        dev_dbg(jzpc->dev, "set pin P%c%u to function %u\n",
 478                        'A' + offt, idx, func);
 479
 480        if (jzpc->version >= ID_JZ4770) {
 481                ingenic_config_pin(jzpc, pin, JZ4770_GPIO_INT, false);
 482                ingenic_config_pin(jzpc, pin, JZ4770_GPIO_MSK, false);
 483                ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, func & 0x2);
 484                ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT0, func & 0x1);
 485        } else {
 486                ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, true);
 487                ingenic_config_pin(jzpc, pin, JZ4740_GPIO_TRIG, func & 0x2);
 488                ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, func > 0);
 489        }
 490
 491        return 0;
 492}
 493
 494static int ingenic_pinmux_set_mux(struct pinctrl_dev *pctldev,
 495                unsigned int selector, unsigned int group)
 496{
 497        struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
 498        struct function_desc *func;
 499        struct group_desc *grp;
 500        unsigned int i;
 501
 502        func = pinmux_generic_get_function(pctldev, selector);
 503        if (!func)
 504                return -EINVAL;
 505
 506        grp = pinctrl_generic_get_group(pctldev, group);
 507        if (!grp)
 508                return -EINVAL;
 509
 510        dev_dbg(pctldev->dev, "enable function %s group %s\n",
 511                func->name, grp->name);
 512
 513        for (i = 0; i < grp->num_pins; i++) {
 514                int *pin_modes = grp->data;
 515
 516                ingenic_pinmux_set_pin_fn(jzpc, grp->pins[i], pin_modes[i]);
 517        }
 518
 519        return 0;
 520}
 521
 522static int ingenic_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
 523                struct pinctrl_gpio_range *range,
 524                unsigned int pin, bool input)
 525{
 526        struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
 527        unsigned int idx = pin % PINS_PER_GPIO_CHIP;
 528        unsigned int offt = pin / PINS_PER_GPIO_CHIP;
 529
 530        dev_dbg(pctldev->dev, "set pin P%c%u to %sput\n",
 531                        'A' + offt, idx, input ? "in" : "out");
 532
 533        if (jzpc->version >= ID_JZ4770) {
 534                ingenic_config_pin(jzpc, pin, JZ4770_GPIO_INT, false);
 535                ingenic_config_pin(jzpc, pin, JZ4770_GPIO_MSK, true);
 536                ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, input);
 537        } else {
 538                ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, false);
 539                ingenic_config_pin(jzpc, pin, JZ4740_GPIO_DIR, input);
 540                ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, false);
 541        }
 542
 543        return 0;
 544}
 545
 546static const struct pinmux_ops ingenic_pmxops = {
 547        .get_functions_count = pinmux_generic_get_function_count,
 548        .get_function_name = pinmux_generic_get_function_name,
 549        .get_function_groups = pinmux_generic_get_function_groups,
 550        .set_mux = ingenic_pinmux_set_mux,
 551        .gpio_set_direction = ingenic_pinmux_gpio_set_direction,
 552};
 553
 554static int ingenic_pinconf_get(struct pinctrl_dev *pctldev,
 555                unsigned int pin, unsigned long *config)
 556{
 557        struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
 558        enum pin_config_param param = pinconf_to_config_param(*config);
 559        unsigned int idx = pin % PINS_PER_GPIO_CHIP;
 560        unsigned int offt = pin / PINS_PER_GPIO_CHIP;
 561        bool pull;
 562
 563        if (jzpc->version >= ID_JZ4770)
 564                pull = !ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_PEN);
 565        else
 566                pull = !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_PULL_DIS);
 567
 568        switch (param) {
 569        case PIN_CONFIG_BIAS_DISABLE:
 570                if (pull)
 571                        return -EINVAL;
 572                break;
 573
 574        case PIN_CONFIG_BIAS_PULL_UP:
 575                if (!pull || !(jzpc->info->pull_ups[offt] & BIT(idx)))
 576                        return -EINVAL;
 577                break;
 578
 579        case PIN_CONFIG_BIAS_PULL_DOWN:
 580                if (!pull || !(jzpc->info->pull_downs[offt] & BIT(idx)))
 581                        return -EINVAL;
 582                break;
 583
 584        default:
 585                return -ENOTSUPP;
 586        }
 587
 588        *config = pinconf_to_config_packed(param, 1);
 589        return 0;
 590}
 591
 592static void ingenic_set_bias(struct ingenic_pinctrl *jzpc,
 593                unsigned int pin, bool enabled)
 594{
 595        if (jzpc->version >= ID_JZ4770)
 596                ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PEN, !enabled);
 597        else
 598                ingenic_config_pin(jzpc, pin, JZ4740_GPIO_PULL_DIS, !enabled);
 599}
 600
 601static int ingenic_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
 602                unsigned long *configs, unsigned int num_configs)
 603{
 604        struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
 605        unsigned int idx = pin % PINS_PER_GPIO_CHIP;
 606        unsigned int offt = pin / PINS_PER_GPIO_CHIP;
 607        unsigned int cfg;
 608
 609        for (cfg = 0; cfg < num_configs; cfg++) {
 610                switch (pinconf_to_config_param(configs[cfg])) {
 611                case PIN_CONFIG_BIAS_DISABLE:
 612                case PIN_CONFIG_BIAS_PULL_UP:
 613                case PIN_CONFIG_BIAS_PULL_DOWN:
 614                        continue;
 615                default:
 616                        return -ENOTSUPP;
 617                }
 618        }
 619
 620        for (cfg = 0; cfg < num_configs; cfg++) {
 621                switch (pinconf_to_config_param(configs[cfg])) {
 622                case PIN_CONFIG_BIAS_DISABLE:
 623                        dev_dbg(jzpc->dev, "disable pull-over for pin P%c%u\n",
 624                                        'A' + offt, idx);
 625                        ingenic_set_bias(jzpc, pin, false);
 626                        break;
 627
 628                case PIN_CONFIG_BIAS_PULL_UP:
 629                        if (!(jzpc->info->pull_ups[offt] & BIT(idx)))
 630                                return -EINVAL;
 631                        dev_dbg(jzpc->dev, "set pull-up for pin P%c%u\n",
 632                                        'A' + offt, idx);
 633                        ingenic_set_bias(jzpc, pin, true);
 634                        break;
 635
 636                case PIN_CONFIG_BIAS_PULL_DOWN:
 637                        if (!(jzpc->info->pull_downs[offt] & BIT(idx)))
 638                                return -EINVAL;
 639                        dev_dbg(jzpc->dev, "set pull-down for pin P%c%u\n",
 640                                        'A' + offt, idx);
 641                        ingenic_set_bias(jzpc, pin, true);
 642                        break;
 643
 644                default:
 645                        unreachable();
 646                }
 647        }
 648
 649        return 0;
 650}
 651
 652static int ingenic_pinconf_group_get(struct pinctrl_dev *pctldev,
 653                unsigned int group, unsigned long *config)
 654{
 655        const unsigned int *pins;
 656        unsigned int i, npins, old = 0;
 657        int ret;
 658
 659        ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
 660        if (ret)
 661                return ret;
 662
 663        for (i = 0; i < npins; i++) {
 664                if (ingenic_pinconf_get(pctldev, pins[i], config))
 665                        return -ENOTSUPP;
 666
 667                /* configs do not match between two pins */
 668                if (i && (old != *config))
 669                        return -ENOTSUPP;
 670
 671                old = *config;
 672        }
 673
 674        return 0;
 675}
 676
 677static int ingenic_pinconf_group_set(struct pinctrl_dev *pctldev,
 678                unsigned int group, unsigned long *configs,
 679                unsigned int num_configs)
 680{
 681        const unsigned int *pins;
 682        unsigned int i, npins;
 683        int ret;
 684
 685        ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
 686        if (ret)
 687                return ret;
 688
 689        for (i = 0; i < npins; i++) {
 690                ret = ingenic_pinconf_set(pctldev,
 691                                pins[i], configs, num_configs);
 692                if (ret)
 693                        return ret;
 694        }
 695
 696        return 0;
 697}
 698
 699static const struct pinconf_ops ingenic_confops = {
 700        .is_generic = true,
 701        .pin_config_get = ingenic_pinconf_get,
 702        .pin_config_set = ingenic_pinconf_set,
 703        .pin_config_group_get = ingenic_pinconf_group_get,
 704        .pin_config_group_set = ingenic_pinconf_group_set,
 705};
 706
 707static const struct regmap_config ingenic_pinctrl_regmap_config = {
 708        .reg_bits = 32,
 709        .val_bits = 32,
 710        .reg_stride = 4,
 711};
 712
 713static const struct of_device_id ingenic_pinctrl_of_match[] = {
 714        { .compatible = "ingenic,jz4740-pinctrl", .data = (void *) ID_JZ4740 },
 715        { .compatible = "ingenic,jz4770-pinctrl", .data = (void *) ID_JZ4770 },
 716        { .compatible = "ingenic,jz4780-pinctrl", .data = (void *) ID_JZ4780 },
 717        {},
 718};
 719
 720int ingenic_pinctrl_probe(struct platform_device *pdev)
 721{
 722        struct device *dev = &pdev->dev;
 723        struct ingenic_pinctrl *jzpc;
 724        struct pinctrl_desc *pctl_desc;
 725        void __iomem *base;
 726        const struct platform_device_id *id = platform_get_device_id(pdev);
 727        const struct of_device_id *of_id = of_match_device(
 728                        ingenic_pinctrl_of_match, dev);
 729        const struct ingenic_chip_info *chip_info;
 730        unsigned int i;
 731        int err;
 732
 733        jzpc = devm_kzalloc(dev, sizeof(*jzpc), GFP_KERNEL);
 734        if (!jzpc)
 735                return -ENOMEM;
 736
 737        base = devm_ioremap_resource(dev,
 738                        platform_get_resource(pdev, IORESOURCE_MEM, 0));
 739        if (IS_ERR(base)) {
 740                dev_err(dev, "Failed to ioremap registers\n");
 741                return PTR_ERR(base);
 742        }
 743
 744        jzpc->map = devm_regmap_init_mmio(dev, base,
 745                        &ingenic_pinctrl_regmap_config);
 746        if (IS_ERR(jzpc->map)) {
 747                dev_err(dev, "Failed to create regmap\n");
 748                return PTR_ERR(jzpc->map);
 749        }
 750
 751        jzpc->dev = dev;
 752
 753        if (of_id)
 754                jzpc->version = (enum jz_version)of_id->data;
 755        else
 756                jzpc->version = (enum jz_version)id->driver_data;
 757
 758        if (jzpc->version >= ID_JZ4770)
 759                chip_info = &jz4770_chip_info;
 760        else
 761                chip_info = &jz4740_chip_info;
 762        jzpc->info = chip_info;
 763
 764        pctl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctl_desc), GFP_KERNEL);
 765        if (!pctl_desc)
 766                return -ENOMEM;
 767
 768        /* fill in pinctrl_desc structure */
 769        pctl_desc->name = dev_name(dev);
 770        pctl_desc->owner = THIS_MODULE;
 771        pctl_desc->pctlops = &ingenic_pctlops;
 772        pctl_desc->pmxops = &ingenic_pmxops;
 773        pctl_desc->confops = &ingenic_confops;
 774        pctl_desc->npins = chip_info->num_chips * PINS_PER_GPIO_CHIP;
 775        pctl_desc->pins = jzpc->pdesc = devm_kzalloc(&pdev->dev,
 776                        sizeof(*jzpc->pdesc) * pctl_desc->npins, GFP_KERNEL);
 777        if (!jzpc->pdesc)
 778                return -ENOMEM;
 779
 780        for (i = 0; i < pctl_desc->npins; i++) {
 781                jzpc->pdesc[i].number = i;
 782                jzpc->pdesc[i].name = kasprintf(GFP_KERNEL, "P%c%d",
 783                                                'A' + (i / PINS_PER_GPIO_CHIP),
 784                                                i % PINS_PER_GPIO_CHIP);
 785        }
 786
 787        jzpc->pctl = devm_pinctrl_register(dev, pctl_desc, jzpc);
 788        if (IS_ERR(jzpc->pctl)) {
 789                dev_err(dev, "Failed to register pinctrl\n");
 790                return PTR_ERR(jzpc->pctl);
 791        }
 792
 793        for (i = 0; i < chip_info->num_groups; i++) {
 794                const struct group_desc *group = &chip_info->groups[i];
 795
 796                err = pinctrl_generic_add_group(jzpc->pctl, group->name,
 797                                group->pins, group->num_pins, group->data);
 798                if (err) {
 799                        dev_err(dev, "Failed to register group %s\n",
 800                                        group->name);
 801                        return err;
 802                }
 803        }
 804
 805        for (i = 0; i < chip_info->num_functions; i++) {
 806                const struct function_desc *func = &chip_info->functions[i];
 807
 808                err = pinmux_generic_add_function(jzpc->pctl, func->name,
 809                                func->group_names, func->num_group_names,
 810                                func->data);
 811                if (err) {
 812                        dev_err(dev, "Failed to register function %s\n",
 813                                        func->name);
 814                        return err;
 815                }
 816        }
 817
 818        dev_set_drvdata(dev, jzpc->map);
 819
 820        if (dev->of_node) {
 821                err = of_platform_populate(dev->of_node, NULL, NULL, dev);
 822                if (err) {
 823                        dev_err(dev, "Failed to probe GPIO devices\n");
 824                        return err;
 825                }
 826        }
 827
 828        return 0;
 829}
 830
 831static const struct platform_device_id ingenic_pinctrl_ids[] = {
 832        { "jz4740-pinctrl", ID_JZ4740 },
 833        { "jz4770-pinctrl", ID_JZ4770 },
 834        { "jz4780-pinctrl", ID_JZ4780 },
 835        {},
 836};
 837
 838static struct platform_driver ingenic_pinctrl_driver = {
 839        .driver = {
 840                .name = "pinctrl-ingenic",
 841                .of_match_table = of_match_ptr(ingenic_pinctrl_of_match),
 842                .suppress_bind_attrs = true,
 843        },
 844        .probe = ingenic_pinctrl_probe,
 845        .id_table = ingenic_pinctrl_ids,
 846};
 847
 848static int __init ingenic_pinctrl_drv_register(void)
 849{
 850        return platform_driver_register(&ingenic_pinctrl_driver);
 851}
 852postcore_initcall(ingenic_pinctrl_drv_register);
 853