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