From: Josep Orga Date: Sun, 19 Apr 2020 12:18:43 +0000 (+0200) Subject: mmc: pwrseq_simple: Add wilc3000 pwrseq adding chip_en gpio and proper power on and... X-Git-Tag: rel_imx_4.19.35_1.1.0-somdevices.0~7 X-Git-Url: https://git.somdevices.com/?a=commitdiff_plain;h=c03a31b459604da0c688c6537f3ebbadeab28d13;p=linux.git mmc: pwrseq_simple: Add wilc3000 pwrseq adding chip_en gpio and proper power on and off sequences. Signed-off-by: Josep Orga --- diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c index a8b9fee4d62a..6ce9ce13507c 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, *values; @@ -50,7 +52,37 @@ static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq, for (i = 0; i < nvalues; i++) values[i] = value; - gpiod_set_array_value_cansleep(nvalues, reset_gpios->desc, values); + if (!IS_ERR(reset_gpios) && !IS_ERR(chip_en_gpios)) { + int *values_chip_en; + int nvalues_chip_en = chip_en_gpios->ndescs; + values_chip_en = kmalloc_array(nvalues_chip_en, sizeof(int), GFP_KERNEL); + if (!values_chip_en) { + kfree(values); + return; + } + for (i = 0; i < nvalues_chip_en; i++) + values_chip_en[i] = value; + + if (!value) { + //Power on sequence + gpiod_set_array_value_cansleep( + nvalues_chip_en, chip_en_gpios->desc, values_chip_en); + msleep(5); + gpiod_set_array_value_cansleep( + nvalues, reset_gpios->desc, values); + } else { + //Power off sequence + gpiod_set_array_value_cansleep( + nvalues, reset_gpios->desc, values); + msleep(5); + gpiod_set_array_value_cansleep( + nvalues_chip_en, chip_en_gpios->desc, values_chip_en); + } + kfree(values_chip_en); + } else { + gpiod_set_array_value_cansleep( + nvalues, reset_gpios->desc, values); + } kfree(values); } } @@ -126,6 +158,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",