From 29c784bdc04f5199f9936b9e8246c3ef7dff67be Mon Sep 17 00:00:00 2001 From: Josep Orga Date: Tue, 14 Apr 2020 19:51:59 +0200 Subject: [PATCH] ARM: Add WILC3000 pwrseq adding chip_en gpio and proper power on and off sequences. Signed-off-by: Josep Orga --- arch/arm/boot/dts/imx6ull-somdevices.dtsi | 4 +-- drivers/mmc/core/pwrseq_simple.c | 36 +++++++++++++++++++++-- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/imx6ull-somdevices.dtsi b/arch/arm/boot/dts/imx6ull-somdevices.dtsi index 5cdb84428a04..4924f847f9fd 100644 --- a/arch/arm/boot/dts/imx6ull-somdevices.dtsi +++ b/arch/arm/boot/dts/imx6ull-somdevices.dtsi @@ -82,8 +82,8 @@ wifi_pwrseq: wifi_pwrseq { compatible = "mmc-pwrseq-simple"; - reset-gpios = <&gpio5 7 GPIO_ACTIVE_LOW>, //RESET - <&gpio5 6 GPIO_ACTIVE_LOW>; //CHIP_EN + reset-gpios = <&gpio5 7 GPIO_ACTIVE_LOW>; //RESET + chip_en-gpios = <&gpio5 6 GPIO_ACTIVE_LOW>; //CHIP_EN post-power-on-delay-ms = <10>; }; }; diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c index 13ef162cf066..4e537e836b28 100644 --- a/drivers/mmc/core/pwrseq_simple.c +++ b/drivers/mmc/core/pwrseq_simple.c @@ -30,6 +30,7 @@ struct mmc_pwrseq_simple { u32 power_off_delay_us; struct clk *ext_clk; struct gpio_descs *reset_gpios; + struct gpio_descs *chip_en_gpios; }; #define to_pwrseq_simple(p) container_of(p, struct mmc_pwrseq_simple, pwrseq) @@ -38,6 +39,7 @@ static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq, int value) { struct gpio_descs *reset_gpios = pwrseq->reset_gpios; + struct gpio_descs *chip_en_gpios = pwrseq->chip_en_gpios; if (!IS_ERR(reset_gpios)) { int i; @@ -46,8 +48,30 @@ static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq, for (i = 0; i < reset_gpios->ndescs; i++) values[i] = value; - gpiod_set_array_value_cansleep( - reset_gpios->ndescs, reset_gpios->desc, values); + if (!IS_ERR(reset_gpios) && !IS_ERR(chip_en_gpios)) { + int values_chip_en[chip_en_gpios->ndescs]; + for (i = 0; i < chip_en_gpios->ndescs; i++) + values_chip_en[i] = value; + + if (!value) { + //Power on sequence + gpiod_set_array_value_cansleep( + chip_en_gpios->ndescs, chip_en_gpios->desc, values); + msleep(5); + gpiod_set_array_value_cansleep( + reset_gpios->ndescs, reset_gpios->desc, values); + } else { + //Power off sequence + gpiod_set_array_value_cansleep( + reset_gpios->ndescs, reset_gpios->desc, values); + msleep(5); + gpiod_set_array_value_cansleep( + chip_en_gpios->ndescs, chip_en_gpios->desc, values); + } + } else { + gpiod_set_array_value_cansleep( + reset_gpios->ndescs, reset_gpios->desc, values); + } } } @@ -122,6 +146,14 @@ static int mmc_pwrseq_simple_probe(struct platform_device *pdev) return PTR_ERR(pwrseq->reset_gpios); } + pwrseq->chip_en_gpios = devm_gpiod_get_array(dev, "chip_en", + GPIOD_OUT_HIGH); + if (IS_ERR(pwrseq->chip_en_gpios) && + PTR_ERR(pwrseq->chip_en_gpios) != -ENOENT && + PTR_ERR(pwrseq->chip_en_gpios) != -ENOSYS) { + return PTR_ERR(pwrseq->chip_en_gpios); + } + device_property_read_u32(dev, "post-power-on-delay-ms", &pwrseq->post_power_on_delay_ms); device_property_read_u32(dev, "power-off-delay-us", -- 2.17.1