lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Sat, 17 Apr 2021 10:46:57 +0100
From:   Paul Cercueil <paul@...pouillou.net>
To:     周琰杰 <zhouyanjie@...yeetech.com>
Cc:     linus.walleij@...aro.org, robh+dt@...nel.org,
        linux-gpio@...r.kernel.org, linux-mips@...r.kernel.org,
        linux-kernel@...r.kernel.org, devicetree@...r.kernel.org,
        hns@...delico.com, paul@...die.org.uk, andy.shevchenko@...il.com,
        dongsheng.qiu@...enic.com, aric.pzqi@...enic.com,
        rick.tyliu@...enic.com, sernia.zhou@...mail.com,
        siyanteng@...ngson.cn
Subject: Re: [PATCH v5 07/11] pinctrl: Ingenic: Add pinctrl driver for JZ4730.

Hi Zhou,

Le sam. 17 avril 2021 à 0:14, 周琰杰 (Zhou Yanjie) 
<zhouyanjie@...yeetech.com> a écrit :
> Add support for probing the pinctrl-ingenic driver on the
> JZ4730 SoC from Ingenic.
> 
> This driver is derived from Paul Boddie. It is worth to
> noting that the JZ4730 SoC is special in having two control
> registers (upper/lower), so add code to handle the JZ4730
> specific register offsets and some register pairs which have
> 2 bits for each GPIO pin.
> 
> Tested-by: H. Nikolaus Schaller <hns@...delico.com>  # on Letux400
> Co-developed-by: Paul Boddie <paul@...die.org.uk>
> Signed-off-by: Paul Boddie <paul@...die.org.uk>
> Signed-off-by: H. Nikolaus Schaller <hns@...delico.com>
> Signed-off-by: 周琰杰 (Zhou Yanjie) <zhouyanjie@...yeetech.com>
> Reviewed-by: Andy Shevchenko <andy.shevchenko@...il.com>
> ---
> 
> Notes:
>     v3:
>     New patch.
> 
>     v3->v4:
>     1.Use "lcd-special" and "lcd-generic" instead "lcd-16bit-tft".
>     2.Adjust function names to avoid confusion.
>     3.Improve the structure of some functions.
>     4.Modify the format of comment.
>     5.Simplify code using GENMASK.
>     6.Drop unnecessary mask.
> 
>     v4->v5:
>     No change.
> 
>  drivers/pinctrl/pinctrl-ingenic.c | 232 
> +++++++++++++++++++++++++++++++++++---
>  1 file changed, 216 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/pinctrl/pinctrl-ingenic.c 
> b/drivers/pinctrl/pinctrl-ingenic.c
> index 009901b..4c48250 100644
> --- a/drivers/pinctrl/pinctrl-ingenic.c
> +++ b/drivers/pinctrl/pinctrl-ingenic.c
> @@ -3,8 +3,8 @@
>   * Ingenic SoCs pinctrl driver
>   *
>   * Copyright (c) 2017 Paul Cercueil <paul@...pouillou.net>
> - * Copyright (c) 2019 周琰杰 (Zhou Yanjie) 
> <zhouyanjie@...yeetech.com>
>   * Copyright (c) 2017, 2019 Paul Boddie <paul@...die.org.uk>
> + * Copyright (c) 2019, 2020 周琰杰 (Zhou Yanjie) 
> <zhouyanjie@...yeetech.com>
>   */
> 
>  #include <linux/compiler.h>
> @@ -29,6 +29,17 @@
>  #define GPIO_PIN					0x00
>  #define GPIO_MSK					0x20
> 
> +#define JZ4730_GPIO_DATA			0x00
> +#define JZ4730_GPIO_GPDIR			0x04
> +#define JZ4730_GPIO_GPPUR			0x0c
> +#define JZ4730_GPIO_GPALR			0x10
> +#define JZ4730_GPIO_GPAUR			0x14
> +#define JZ4730_GPIO_GPIDLR			0x18
> +#define JZ4730_GPIO_GPIDUR			0x1c
> +#define JZ4730_GPIO_GPIER			0x20
> +#define JZ4730_GPIO_GPIMR			0x24
> +#define JZ4730_GPIO_GPFR			0x28
> +
>  #define JZ4740_GPIO_DATA			0x10
>  #define JZ4740_GPIO_PULL_DIS		0x30
>  #define JZ4740_GPIO_FUNC			0x40
> @@ -57,6 +68,7 @@
>  #define GPIO_PULL_DOWN				2
> 
>  #define PINS_PER_GPIO_CHIP			32
> +#define JZ4730_PINS_PER_PAIRED_REG	16
> 
>  #define INGENIC_PIN_GROUP_FUNCS(name, id, funcs)		\
>  	{						\
> @@ -70,6 +82,7 @@
>  	INGENIC_PIN_GROUP_FUNCS(name, id, (void *)(func))
> 
>  enum jz_version {
> +	ID_JZ4730,
>  	ID_JZ4740,
>  	ID_JZ4725B,
>  	ID_JZ4760,
> @@ -110,6 +123,99 @@ struct ingenic_gpio_chip {
>  	unsigned int irq, reg_base;
>  };
> 
> +static const u32 jz4730_pull_ups[4] = {
> +	0x3fa3320f, 0xf200ffff, 0xffffffff, 0xffffffff,
> +};
> +
> +static const u32 jz4730_pull_downs[4] = {
> +	0x00000df0, 0x0dff0000, 0x00000000, 0x00000000,
> +};
> +
> +static int jz4730_mmc_1bit_pins[] = { 0x27, 0x26, 0x22, };
> +static int jz4730_mmc_4bit_pins[] = { 0x23, 0x24, 0x25, };
> +static int jz4730_uart0_data_pins[] = { 0x7e, 0x7f, };
> +static int jz4730_uart1_data_pins[] = { 0x18, 0x19, };
> +static int jz4730_uart2_data_pins[] = { 0x6f, 0x7d, };
> +static int jz4730_uart3_data_pins[] = { 0x10, 0x15, };
> +static int jz4730_uart3_hwflow_pins[] = { 0x11, 0x17, };
> +static int jz4730_lcd_8bit_pins[] = {
> +	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
> +	0x3a, 0x39, 0x38,
> +};
> +static int jz4730_lcd_16bit_pins[] = {
> +	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
> +};
> +static int jz4730_lcd_special_pins[] = { 0x3d, 0x3c, 0x3e, 0x3f, };
> +static int jz4730_lcd_generic_pins[] = { 0x3b, };
> +static int jz4730_nand_cs1_pins[] = { 0x53, };
> +static int jz4730_nand_cs2_pins[] = { 0x54, };
> +static int jz4730_nand_cs3_pins[] = { 0x55, };
> +static int jz4730_nand_cs4_pins[] = { 0x56, };
> +static int jz4730_nand_cs5_pins[] = { 0x57, };
> +static int jz4730_pwm_pwm0_pins[] = { 0x5e, };
> +static int jz4730_pwm_pwm1_pins[] = { 0x5f, };
> +
> +static u8 jz4730_lcd_8bit_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 
> 2, };
> +
> +static const struct group_desc jz4730_groups[] = {
> +	INGENIC_PIN_GROUP("mmc-1bit", jz4730_mmc_1bit, 1),
> +	INGENIC_PIN_GROUP("mmc-4bit", jz4730_mmc_4bit, 1),
> +	INGENIC_PIN_GROUP("uart0-data", jz4730_uart0_data, 1),
> +	INGENIC_PIN_GROUP("uart1-data", jz4730_uart1_data, 1),
> +	INGENIC_PIN_GROUP("uart2-data", jz4730_uart2_data, 1),
> +	INGENIC_PIN_GROUP("uart3-data", jz4730_uart3_data, 1),
> +	INGENIC_PIN_GROUP("uart3-hwflow", jz4730_uart3_hwflow, 1),
> +	INGENIC_PIN_GROUP_FUNCS("lcd-8bit", jz4730_lcd_8bit, 
> jz4730_lcd_8bit_funcs),
> +	INGENIC_PIN_GROUP("lcd-16bit", jz4730_lcd_16bit, 1),
> +	INGENIC_PIN_GROUP("lcd-special", jz4730_lcd_special, 1),
> +	INGENIC_PIN_GROUP("lcd-generic", jz4730_lcd_generic, 1),
> +	INGENIC_PIN_GROUP("nand-cs1", jz4730_nand_cs1, 1),
> +	INGENIC_PIN_GROUP("nand-cs2", jz4730_nand_cs2, 1),
> +	INGENIC_PIN_GROUP("nand-cs3", jz4730_nand_cs3, 1),
> +	INGENIC_PIN_GROUP("nand-cs4", jz4730_nand_cs4, 1),
> +	INGENIC_PIN_GROUP("nand-cs5", jz4730_nand_cs5, 1),
> +	INGENIC_PIN_GROUP("pwm0", jz4730_pwm_pwm0, 1),
> +	INGENIC_PIN_GROUP("pwm1", jz4730_pwm_pwm1, 1),
> +};
> +
> +static const char *jz4730_mmc_groups[] = { "mmc-1bit", "mmc-4bit", };
> +static const char *jz4730_uart0_groups[] = { "uart0-data", };
> +static const char *jz4730_uart1_groups[] = { "uart1-data", };
> +static const char *jz4730_uart2_groups[] = { "uart2-data", };
> +static const char *jz4730_uart3_groups[] = { "uart3-data", 
> "uart3-hwflow", };
> +static const char *jz4730_lcd_groups[] = {
> +	"lcd-8bit", "lcd-16bit", "lcd-special", "lcd-generic",
> +};
> +static const char *jz4730_nand_groups[] = {
> +	"nand-cs1", "nand-cs2", "nand-cs3", "nand-cs4", "nand-cs5",
> +};
> +static const char *jz4730_pwm0_groups[] = { "pwm0", };
> +static const char *jz4730_pwm1_groups[] = { "pwm1", };
> +
> +static const struct function_desc jz4730_functions[] = {
> +	{ "mmc", jz4730_mmc_groups, ARRAY_SIZE(jz4730_mmc_groups), },
> +	{ "uart0", jz4730_uart0_groups, ARRAY_SIZE(jz4730_uart0_groups), },
> +	{ "uart1", jz4730_uart1_groups, ARRAY_SIZE(jz4730_uart1_groups), },
> +	{ "uart2", jz4730_uart2_groups, ARRAY_SIZE(jz4730_uart2_groups), },
> +	{ "uart3", jz4730_uart3_groups, ARRAY_SIZE(jz4730_uart3_groups), },
> +	{ "lcd", jz4730_lcd_groups, ARRAY_SIZE(jz4730_lcd_groups), },
> +	{ "nand", jz4730_nand_groups, ARRAY_SIZE(jz4730_nand_groups), },
> +	{ "pwm0", jz4730_pwm0_groups, ARRAY_SIZE(jz4730_pwm0_groups), },
> +	{ "pwm1", jz4730_pwm1_groups, ARRAY_SIZE(jz4730_pwm1_groups), },
> +};
> +
> +static const struct ingenic_chip_info jz4730_chip_info = {
> +	.num_chips = 4,
> +	.reg_offset = 0x30,
> +	.version = ID_JZ4730,
> +	.groups = jz4730_groups,
> +	.num_groups = ARRAY_SIZE(jz4730_groups),
> +	.functions = jz4730_functions,
> +	.num_functions = ARRAY_SIZE(jz4730_functions),
> +	.pull_ups = jz4730_pull_ups,
> +	.pull_downs = jz4730_pull_downs,
> +};
> +
>  static const u32 jz4740_pull_ups[4] = {
>  	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
>  };
> @@ -1681,6 +1787,12 @@ static u32 ingenic_gpio_read_reg(struct 
> ingenic_gpio_chip *jzgc, u8 reg)
>  static void ingenic_gpio_set_bit(struct ingenic_gpio_chip *jzgc,
>  		u8 reg, u8 offset, bool set)
>  {
> +	if (jzgc->jzpc->info->version == ID_JZ4730) {
> +		regmap_update_bits(jzgc->jzpc->map, jzgc->reg_base + reg,
> +				BIT(offset), set ? BIT(offset) : 0);
> +		return;
> +	}
> +
>  	if (set)
>  		reg = REG_SET(reg);
>  	else
> @@ -1708,6 +1820,20 @@ static void 
> ingenic_gpio_shadow_set_bit_load(struct ingenic_gpio_chip *jzgc)
>  			jzgc->gc.base / PINS_PER_GPIO_CHIP);
>  }
> 
> +static void jz4730_gpio_set_bits(struct ingenic_gpio_chip *jzgc,
> +		u8 reg_upper, u8 reg_lower, u8 offset, u8 value)
> +{
> +	/*
> +	 * JZ4730 function and IRQ registers support two-bits-per-pin
> +	 * definitions, split into two groups of 16.
> +	 */
> +	u8 reg = offset < JZ4730_PINS_PER_PAIRED_REG ? reg_lower : 
> reg_upper;
> +	unsigned int idx = offset % JZ4730_PINS_PER_PAIRED_REG;
> +	unsigned int mask = GENMASK(1, 0) << idx * 2;
> +
> +	regmap_update_bits(jzgc->jzpc->map, jzgc->reg_base + reg, mask, 
> value << (idx * 2));
> +}
> +
>  static inline bool ingenic_gpio_get_value(struct ingenic_gpio_chip 
> *jzgc,
>  					  u8 offset)
>  {
> @@ -1721,8 +1847,10 @@ static void ingenic_gpio_set_value(struct 
> ingenic_gpio_chip *jzgc,
>  {
>  	if (jzgc->jzpc->info->version >= ID_JZ4770)
>  		ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_PAT0, offset, !!value);
> -	else
> +	else if (jzgc->jzpc->info->version >= ID_JZ4740)
>  		ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_DATA, offset, !!value);
> +	else
> +		ingenic_gpio_set_bit(jzgc, JZ4730_GPIO_DATA, offset, !!value);
>  }
> 
>  static void irq_set_type(struct ingenic_gpio_chip *jzgc,
> @@ -1752,9 +1880,14 @@ static void irq_set_type(struct 
> ingenic_gpio_chip *jzgc,
>  	if (jzgc->jzpc->info->version >= ID_JZ4770) {
>  		reg1 = JZ4770_GPIO_PAT1;
>  		reg2 = JZ4770_GPIO_PAT0;
> -	} else {
> +	} else if (jzgc->jzpc->info->version >= ID_JZ4740) {
>  		reg1 = JZ4740_GPIO_TRIG;
>  		reg2 = JZ4740_GPIO_DIR;
> +	} else {
> +		ingenic_gpio_set_bit(jzgc, JZ4730_GPIO_GPDIR, offset, false);
> +		jz4730_gpio_set_bits(jzgc, JZ4730_GPIO_GPIDUR,
> +				JZ4730_GPIO_GPIDLR, offset, (val2 << 1) | val1);
> +		return;
>  	}
> 
>  	if (jzgc->jzpc->info->version >= ID_X1000) {
> @@ -1771,16 +1904,24 @@ static void ingenic_gpio_irq_mask(struct 
> irq_data *irqd)
>  {
>  	struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
>  	struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
> +	int irq = irqd->hwirq;
> 
> -	ingenic_gpio_set_bit(jzgc, GPIO_MSK, irqd->hwirq, true);
> +	if (jzgc->jzpc->info->version >= ID_JZ4740)
> +		ingenic_gpio_set_bit(jzgc, GPIO_MSK, irq, true);
> +	else
> +		ingenic_gpio_set_bit(jzgc, JZ4730_GPIO_GPIMR, irq, true);
>  }
> 
>  static void ingenic_gpio_irq_unmask(struct irq_data *irqd)
>  {
>  	struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
>  	struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
> +	int irq = irqd->hwirq;
> 
> -	ingenic_gpio_set_bit(jzgc, GPIO_MSK, irqd->hwirq, false);
> +	if (jzgc->jzpc->info->version >= ID_JZ4740)
> +		ingenic_gpio_set_bit(jzgc, GPIO_MSK, irq, false);
> +	else
> +		ingenic_gpio_set_bit(jzgc, JZ4730_GPIO_GPIMR, irq, false);
>  }
> 
>  static void ingenic_gpio_irq_enable(struct irq_data *irqd)
> @@ -1791,8 +1932,10 @@ static void ingenic_gpio_irq_enable(struct 
> irq_data *irqd)
> 
>  	if (jzgc->jzpc->info->version >= ID_JZ4770)
>  		ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_INT, irq, true);
> -	else
> +	else if (jzgc->jzpc->info->version >= ID_JZ4740)
>  		ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, true);
> +	else
> +		ingenic_gpio_set_bit(jzgc, JZ4730_GPIO_GPIER, irq, true);
> 
>  	ingenic_gpio_irq_unmask(irqd);
>  }
> @@ -1807,8 +1950,10 @@ static void ingenic_gpio_irq_disable(struct 
> irq_data *irqd)
> 
>  	if (jzgc->jzpc->info->version >= ID_JZ4770)
>  		ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_INT, irq, false);
> -	else
> +	else if (jzgc->jzpc->info->version >= ID_JZ4740)
>  		ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, false);
> +	else
> +		ingenic_gpio_set_bit(jzgc, JZ4730_GPIO_GPIER, irq, false);
>  }
> 
>  static void ingenic_gpio_irq_ack(struct irq_data *irqd)
> @@ -1832,8 +1977,10 @@ static void ingenic_gpio_irq_ack(struct 
> irq_data *irqd)
> 
>  	if (jzgc->jzpc->info->version >= ID_JZ4770)
>  		ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_FLAG, irq, false);
> -	else
> +	else if (jzgc->jzpc->info->version >= ID_JZ4740)
>  		ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_DATA, irq, true);
> +	else
> +		ingenic_gpio_set_bit(jzgc, JZ4730_GPIO_GPFR, irq, false);
>  }
> 
>  static int ingenic_gpio_irq_set_type(struct irq_data *irqd, unsigned 
> int type)
> @@ -1889,8 +2036,10 @@ static void ingenic_gpio_irq_handler(struct 
> irq_desc *desc)
> 
>  	if (jzgc->jzpc->info->version >= ID_JZ4770)
>  		flag = ingenic_gpio_read_reg(jzgc, JZ4770_GPIO_FLAG);
> -	else
> +	else if (jzgc->jzpc->info->version >= ID_JZ4740)
>  		flag = ingenic_gpio_read_reg(jzgc, JZ4740_GPIO_FLAG);
> +	else
> +		flag = ingenic_gpio_read_reg(jzgc, JZ4730_GPIO_GPFR);
> 
>  	for_each_set_bit(i, &flag, 32)
>  		generic_handle_irq(irq_linear_revmap(gc->irq.domain, i));
> @@ -1931,8 +2080,21 @@ static inline void ingenic_config_pin(struct 
> ingenic_pinctrl *jzpc,
>  	unsigned int idx = pin % PINS_PER_GPIO_CHIP;
>  	unsigned int offt = pin / PINS_PER_GPIO_CHIP;
> 
> -	regmap_write(jzpc->map, offt * jzpc->info->reg_offset +
> -			(set ? REG_SET(reg) : REG_CLEAR(reg)), BIT(idx));
> +	if (set) {
> +		if (jzpc->info->version >= ID_JZ4740)
> +			regmap_write(jzpc->map, offt * jzpc->info->reg_offset +
> +					REG_SET(reg), BIT(idx));
> +		else
> +			regmap_set_bits(jzpc->map, offt * jzpc->info->reg_offset +
> +					reg, BIT(idx));
> +	} else {
> +		if (jzpc->info->version >= ID_JZ4740)
> +			regmap_write(jzpc->map, offt * jzpc->info->reg_offset +
> +					REG_CLEAR(reg), BIT(idx));
> +		else
> +			regmap_clear_bits(jzpc->map, offt * jzpc->info->reg_offset +
> +					reg, BIT(idx));

You can cache (offt * jzpc->info->reg_offset) into a variable, then you 
wouldn't need to break lines like that.

Not really worth a respin though, so:

Reviewed-by: Paul Cercueil <paul@...pouillou.net>

Cheers,
-Paul

> +	}
>  }
> 
>  static inline void ingenic_shadow_config_pin(struct ingenic_pinctrl 
> *jzpc,
> @@ -1951,6 +2113,22 @@ static inline void 
> ingenic_shadow_config_pin_load(struct ingenic_pinctrl *jzpc,
>  			pin / PINS_PER_GPIO_CHIP);
>  }
> 
> +static inline void jz4730_config_pin_function(struct ingenic_pinctrl 
> *jzpc,
> +		unsigned int pin, u8 reg_upper, u8 reg_lower, u8 value)
> +{
> +	/*
> +	 * JZ4730 function and IRQ registers support two-bits-per-pin
> +	 * definitions, split into two groups of 16.
> +	 */
> +	unsigned int idx = pin % JZ4730_PINS_PER_PAIRED_REG;
> +	unsigned int mask = GENMASK(1, 0) << idx * 2;
> +	unsigned int offt = pin / PINS_PER_GPIO_CHIP;
> +	u8 reg = (pin % PINS_PER_GPIO_CHIP) < JZ4730_PINS_PER_PAIRED_REG ? 
> reg_lower : reg_upper;
> +
> +	regmap_update_bits(jzpc->map, offt * jzpc->info->reg_offset + reg,
> +			mask, value << (idx * 2));
> +}
> +
>  static inline bool ingenic_get_pin_config(struct ingenic_pinctrl 
> *jzpc,
>  		unsigned int pin, u8 reg)
>  {
> @@ -1974,6 +2152,10 @@ static int ingenic_gpio_get_direction(struct 
> gpio_chip *gc, unsigned int offset)
>  		    ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_PAT1))
>  			return GPIO_LINE_DIRECTION_IN;
>  		return GPIO_LINE_DIRECTION_OUT;
> +	} else if (jzpc->info->version == ID_JZ4730) {
> +		if (!ingenic_get_pin_config(jzpc, pin, JZ4730_GPIO_GPDIR))
> +			return GPIO_LINE_DIRECTION_IN;
> +		return GPIO_LINE_DIRECTION_OUT;
>  	}
> 
>  	if (ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_SELECT))
> @@ -2032,10 +2214,13 @@ static int ingenic_pinmux_set_pin_fn(struct 
> ingenic_pinctrl *jzpc,
>  		ingenic_config_pin(jzpc, pin, GPIO_MSK, false);
>  		ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, func & 0x2);
>  		ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT0, func & 0x1);
> -	} else {
> +	} else if (jzpc->info->version >= ID_JZ4740) {
>  		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, true);
>  		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_TRIG, func & 0x2);
>  		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, func & 0x1);
> +	} else {
> +		ingenic_config_pin(jzpc, pin, JZ4730_GPIO_GPIER, false);
> +		jz4730_config_pin_function(jzpc, pin, JZ4730_GPIO_GPAUR, 
> JZ4730_GPIO_GPALR, func);
>  	}
> 
>  	return 0;
> @@ -2096,10 +2281,14 @@ static int 
> ingenic_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
>  		ingenic_config_pin(jzpc, pin, JZ4770_GPIO_INT, false);
>  		ingenic_config_pin(jzpc, pin, GPIO_MSK, true);
>  		ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, input);
> -	} else {
> +	} else if (jzpc->info->version >= ID_JZ4740) {
>  		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, false);
>  		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_DIR, !input);
>  		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, false);
> +	} else {
> +		ingenic_config_pin(jzpc, pin, JZ4730_GPIO_GPIER, false);
> +		ingenic_config_pin(jzpc, pin, JZ4730_GPIO_GPDIR, !input);
> +		jz4730_config_pin_function(jzpc, pin, JZ4730_GPIO_GPAUR, 
> JZ4730_GPIO_GPALR, 0);
>  	}
> 
>  	return 0;
> @@ -2142,8 +2331,10 @@ static int ingenic_pinconf_get(struct 
> pinctrl_dev *pctldev,
>  	} else {
>  		if (jzpc->info->version >= ID_JZ4770)
>  			pull = !ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_PEN);
> -		else
> +		else if (jzpc->info->version >= ID_JZ4740)
>  			pull = !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_PULL_DIS);
> +		else
> +			pull = ingenic_get_pin_config(jzpc, pin, JZ4730_GPIO_GPPUR);
> 
>  		pullup = pull && (jzpc->info->pull_ups[offt] & BIT(idx));
>  		pulldown = pull && (jzpc->info->pull_downs[offt] & BIT(idx));
> @@ -2196,8 +2387,10 @@ static void ingenic_set_bias(struct 
> ingenic_pinctrl *jzpc,
> 
>  	} else if (jzpc->info->version >= ID_JZ4770) {
>  		ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PEN, !bias);
> -	} else {
> +	} else if (jzpc->info->version >= ID_JZ4740) {
>  		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_PULL_DIS, !bias);
> +	} else {
> +		ingenic_config_pin(jzpc, pin, JZ4730_GPIO_GPPUR, bias);
>  	}
>  }
> 
> @@ -2206,8 +2399,10 @@ static void ingenic_set_output_level(struct 
> ingenic_pinctrl *jzpc,
>  {
>  	if (jzpc->info->version >= ID_JZ4770)
>  		ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT0, high);
> -	else
> +	else if (jzpc->info->version >= ID_JZ4740)
>  		ingenic_config_pin(jzpc, pin, JZ4740_GPIO_DATA, high);
> +	else
> +		ingenic_config_pin(jzpc, pin, JZ4730_GPIO_DATA, high);
>  }
> 
>  static int ingenic_pinconf_set(struct pinctrl_dev *pctldev, unsigned 
> int pin,
> @@ -2336,6 +2531,7 @@ static const struct regmap_config 
> ingenic_pinctrl_regmap_config = {
>  };
> 
>  static const struct of_device_id ingenic_gpio_of_match[] __initconst 
> = {
> +	{ .compatible = "ingenic,jz4730-gpio", },
>  	{ .compatible = "ingenic,jz4740-gpio", },
>  	{ .compatible = "ingenic,jz4725b-gpio", },
>  	{ .compatible = "ingenic,jz4760-gpio", },
> @@ -2530,6 +2726,10 @@ static int __init ingenic_pinctrl_probe(struct 
> platform_device *pdev)
> 
>  static const struct of_device_id ingenic_pinctrl_of_match[] = {
>  	{
> +		.compatible = "ingenic,jz4730-pinctrl",
> +		.data = IF_ENABLED(CONFIG_MACH_JZ4730, &jz4730_chip_info)
> +	},
> +	{
>  		.compatible = "ingenic,jz4740-pinctrl",
>  		.data = IF_ENABLED(CONFIG_MACH_JZ4740, &jz4740_chip_info)
>  	},
> --
> 2.7.4
> 


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ