Skip to content

Commit 0b5d5c4

Browse files
Marek Vasutstorulf
authored andcommitted
mmc: pwrseq: sd8787: Fix WILC CHIP_EN and RESETN toggling order
Chapter "5.3 Power-Up/Down Sequence" of WILC1000 [1] and WILC3000 [2] states that CHIP_EN must be pulled HIGH first, RESETN second. Fix the order of these signals in the driver. Use the mmc_pwrseq_ops as driver data as the delay between signals is specific to SDIO card type anyway. [1] https://ww1.microchip.com/downloads/aemDocuments/documents/WSG/ProductDocuments/DataSheets/ATWILC1000-MR110XB-IEEE-802.11-b-g-n-Link-Controller-Module-DS70005326E.pdf [2] https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/IEEE-802.11-b-g-n-Link-Controller-Module-with-Integrated-Bluetooth-5.0-DS70005327B.pdf Fixes: b2832b9 ("mmc: pwrseq: sd8787: add support for wilc1000") Signed-off-by: Marek Vasut <[email protected]> Reviewed-by: Claudiu Beznea <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Ulf Hansson <[email protected]>
1 parent a99d21c commit 0b5d5c4

File tree

1 file changed

+26
-8
lines changed

1 file changed

+26
-8
lines changed

drivers/mmc/core/pwrseq_sd8787.c

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ struct mmc_pwrseq_sd8787 {
2828
struct mmc_pwrseq pwrseq;
2929
struct gpio_desc *reset_gpio;
3030
struct gpio_desc *pwrdn_gpio;
31-
u32 reset_pwrdwn_delay_ms;
3231
};
3332

3433
#define to_pwrseq_sd8787(p) container_of(p, struct mmc_pwrseq_sd8787, pwrseq)
@@ -39,7 +38,7 @@ static void mmc_pwrseq_sd8787_pre_power_on(struct mmc_host *host)
3938

4039
gpiod_set_value_cansleep(pwrseq->reset_gpio, 1);
4140

42-
msleep(pwrseq->reset_pwrdwn_delay_ms);
41+
msleep(300);
4342
gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 1);
4443
}
4544

@@ -51,17 +50,37 @@ static void mmc_pwrseq_sd8787_power_off(struct mmc_host *host)
5150
gpiod_set_value_cansleep(pwrseq->reset_gpio, 0);
5251
}
5352

53+
static void mmc_pwrseq_wilc1000_pre_power_on(struct mmc_host *host)
54+
{
55+
struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
56+
57+
/* The pwrdn_gpio is really CHIP_EN, reset_gpio is RESETN */
58+
gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 1);
59+
msleep(5);
60+
gpiod_set_value_cansleep(pwrseq->reset_gpio, 1);
61+
}
62+
63+
static void mmc_pwrseq_wilc1000_power_off(struct mmc_host *host)
64+
{
65+
struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
66+
67+
gpiod_set_value_cansleep(pwrseq->reset_gpio, 0);
68+
gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 0);
69+
}
70+
5471
static const struct mmc_pwrseq_ops mmc_pwrseq_sd8787_ops = {
5572
.pre_power_on = mmc_pwrseq_sd8787_pre_power_on,
5673
.power_off = mmc_pwrseq_sd8787_power_off,
5774
};
5875

59-
static const u32 sd8787_delay_ms = 300;
60-
static const u32 wilc1000_delay_ms = 5;
76+
static const struct mmc_pwrseq_ops mmc_pwrseq_wilc1000_ops = {
77+
.pre_power_on = mmc_pwrseq_wilc1000_pre_power_on,
78+
.power_off = mmc_pwrseq_wilc1000_power_off,
79+
};
6180

6281
static const struct of_device_id mmc_pwrseq_sd8787_of_match[] = {
63-
{ .compatible = "mmc-pwrseq-sd8787", .data = &sd8787_delay_ms },
64-
{ .compatible = "mmc-pwrseq-wilc1000", .data = &wilc1000_delay_ms },
82+
{ .compatible = "mmc-pwrseq-sd8787", .data = &mmc_pwrseq_sd8787_ops },
83+
{ .compatible = "mmc-pwrseq-wilc1000", .data = &mmc_pwrseq_wilc1000_ops },
6584
{/* sentinel */},
6685
};
6786
MODULE_DEVICE_TABLE(of, mmc_pwrseq_sd8787_of_match);
@@ -77,7 +96,6 @@ static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev)
7796
return -ENOMEM;
7897

7998
match = of_match_node(mmc_pwrseq_sd8787_of_match, pdev->dev.of_node);
80-
pwrseq->reset_pwrdwn_delay_ms = *(u32 *)match->data;
8199

82100
pwrseq->pwrdn_gpio = devm_gpiod_get(dev, "powerdown", GPIOD_OUT_LOW);
83101
if (IS_ERR(pwrseq->pwrdn_gpio))
@@ -88,7 +106,7 @@ static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev)
88106
return PTR_ERR(pwrseq->reset_gpio);
89107

90108
pwrseq->pwrseq.dev = dev;
91-
pwrseq->pwrseq.ops = &mmc_pwrseq_sd8787_ops;
109+
pwrseq->pwrseq.ops = match->data;
92110
pwrseq->pwrseq.owner = THIS_MODULE;
93111
platform_set_drvdata(pdev, pwrseq);
94112

0 commit comments

Comments
 (0)