Skip to content

Commit 1c8ce27

Browse files
committed
drivers: disk: sdmmc_stm32: power up on request
Move power configuration from the device init function into the `DISK_IOCTL_CTRL_INIT` and `DISK_IOCTL_CTRL_DEINIT` handlers. If `pwr-gpios` is defined, this ensures that the card is not powered up until requested, and enables power down the card when not in use. This behaviour matches the implementation for `sdhc_spi`. Signed-off-by: Jordan Yates <[email protected]>
1 parent 2afd255 commit 1c8ce27

File tree

1 file changed

+55
-44
lines changed

1 file changed

+55
-44
lines changed

drivers/disk/sdmmc_stm32.c

Lines changed: 55 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -277,34 +277,65 @@ static int stm32_sdmmc_dma_deinit(struct stm32_sdmmc_priv *priv)
277277

278278
#endif
279279

280+
/* Forward declarations */
281+
static int stm32_sdmmc_pwr_on(struct stm32_sdmmc_priv *priv);
282+
static int stm32_sdmmc_pwr_off(struct stm32_sdmmc_priv *priv);
283+
static int stm32_sdmmc_card_detect_init(struct stm32_sdmmc_priv *priv);
284+
static bool stm32_sdmmc_card_present(struct stm32_sdmmc_priv *priv);
285+
static int stm32_sdmmc_card_detect_uninit(struct stm32_sdmmc_priv *priv);
286+
280287
static int stm32_sdmmc_access_init(struct disk_info *disk)
281288
{
282289
const struct device *dev = disk->dev;
283290
struct stm32_sdmmc_priv *priv = dev->data;
284291
int err;
285292

286-
if (priv->status == DISK_STATUS_NOMEDIA) {
287-
return -ENODEV;
293+
err = stm32_sdmmc_pwr_on(priv);
294+
if (err) {
295+
return -EIO;
296+
}
297+
298+
/* Configure dt provided device signals when available */
299+
err = pinctrl_apply_state(priv->pcfg, PINCTRL_STATE_DEFAULT);
300+
if (err < 0) {
301+
stm32_sdmmc_pwr_off(priv);
302+
return err;
303+
}
304+
305+
#if !defined(CONFIG_SDMMC_STM32_EMMC)
306+
err = stm32_sdmmc_card_detect_init(priv);
307+
if (err) {
308+
stm32_sdmmc_pwr_off(priv);
309+
return err;
310+
}
311+
#endif
312+
313+
if (stm32_sdmmc_card_present(priv)) {
314+
priv->status = DISK_STATUS_UNINIT;
315+
} else {
316+
priv->status = DISK_STATUS_NOMEDIA;
317+
err = -ENODEV;
318+
goto error;
288319
}
289320

290321
#if STM32_SDMMC_USE_DMA
291322
err = stm32_sdmmc_dma_init(priv);
292323
if (err) {
293324
LOG_ERR("DMA init failed");
294-
return err;
325+
goto error;
295326
}
296327
#endif
297328

298329
err = stm32_sdmmc_clock_enable(priv);
299330
if (err) {
300331
LOG_ERR("failed to init clocks");
301-
return err;
332+
goto error;
302333
}
303334

304335
err = reset_line_toggle_dt(&priv->reset);
305336
if (err) {
306337
LOG_ERR("failed to reset peripheral");
307-
return err;
338+
goto error;
308339
}
309340

310341
#ifdef CONFIG_SDMMC_STM32_EMMC
@@ -314,7 +345,8 @@ static int stm32_sdmmc_access_init(struct disk_info *disk)
314345
#endif
315346
if (err != HAL_OK) {
316347
LOG_ERR("failed to init stm32_sdmmc (ErrorCode 0x%X)", priv->hsd.ErrorCode);
317-
return -EIO;
348+
err = -EIO;
349+
goto error;
318350
}
319351

320352
#ifdef CONFIG_SDMMC_STM32_HWFC
@@ -323,6 +355,12 @@ static int stm32_sdmmc_access_init(struct disk_info *disk)
323355

324356
priv->status = DISK_STATUS_OK;
325357
return 0;
358+
error:
359+
#if !defined(CONFIG_SDMMC_STM32_EMMC)
360+
stm32_sdmmc_card_detect_uninit(priv);
361+
#endif
362+
stm32_sdmmc_pwr_off(priv);
363+
return err;
326364
}
327365

328366
static int stm32_sdmmc_access_deinit(struct stm32_sdmmc_priv *priv)
@@ -348,6 +386,11 @@ static int stm32_sdmmc_access_deinit(struct stm32_sdmmc_priv *priv)
348386
return err;
349387
}
350388

389+
#if !defined(CONFIG_SDMMC_STM32_EMMC)
390+
stm32_sdmmc_card_detect_uninit(priv);
391+
#endif
392+
stm32_sdmmc_pwr_off(priv);
393+
351394
priv->status = DISK_STATUS_UNINIT;
352395
return 0;
353396
}
@@ -646,7 +689,7 @@ static int stm32_sdmmc_card_detect_uninit(struct stm32_sdmmc_priv *priv)
646689
}
647690
#endif /* !CONFIG_SDMMC_STM32_EMMC */
648691

649-
static int stm32_sdmmc_pwr_init(struct stm32_sdmmc_priv *priv)
692+
static int stm32_sdmmc_pwr_on(struct stm32_sdmmc_priv *priv)
650693
{
651694
int err;
652695

@@ -668,21 +711,20 @@ static int stm32_sdmmc_pwr_init(struct stm32_sdmmc_priv *priv)
668711
return 0;
669712
}
670713

671-
static int stm32_sdmmc_pwr_uninit(struct stm32_sdmmc_priv *priv)
714+
static int stm32_sdmmc_pwr_off(struct stm32_sdmmc_priv *priv)
672715
{
673716
if (!priv->pe.port) {
674717
return 0;
675718
}
676719

677-
gpio_pin_configure_dt(&priv->pe, GPIO_DISCONNECTED);
720+
gpio_pin_configure_dt(&priv->pe, GPIO_OUTPUT_INACTIVE);
678721
return 0;
679722
}
680723

681724
static int disk_stm32_sdmmc_init(const struct device *dev)
682725
{
683726
struct stm32_sdmmc_priv *priv = dev->data;
684727
const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
685-
int err;
686728

687729
if (!device_is_ready(clk)) {
688730
LOG_ERR("clock control device not ready");
@@ -694,12 +736,6 @@ static int disk_stm32_sdmmc_init(const struct device *dev)
694736
return -ENODEV;
695737
}
696738

697-
/* Configure dt provided device signals when available */
698-
err = pinctrl_apply_state(priv->pcfg, PINCTRL_STATE_DEFAULT);
699-
if (err < 0) {
700-
return err;
701-
}
702-
703739
priv->irq_config(dev);
704740

705741
/* Initialize semaphores */
@@ -708,38 +744,13 @@ static int disk_stm32_sdmmc_init(const struct device *dev)
708744

709745
#if !defined(CONFIG_SDMMC_STM32_EMMC)
710746
k_work_init(&priv->work, stm32_sdmmc_cd_handler);
711-
712-
err = stm32_sdmmc_card_detect_init(priv);
713-
if (err) {
714-
return err;
715-
}
716747
#endif
717748

718-
err = stm32_sdmmc_pwr_init(priv);
719-
if (err) {
720-
goto err_card_detect;
721-
}
722-
723-
if (stm32_sdmmc_card_present(priv)) {
724-
priv->status = DISK_STATUS_UNINIT;
725-
} else {
726-
priv->status = DISK_STATUS_NOMEDIA;
727-
}
749+
/* Ensure off by default */
750+
stm32_sdmmc_pwr_off(priv);
728751

729752
stm32_sdmmc_info.dev = dev;
730-
err = disk_access_register(&stm32_sdmmc_info);
731-
if (err) {
732-
goto err_pwr;
733-
}
734-
return 0;
735-
736-
err_pwr:
737-
stm32_sdmmc_pwr_uninit(priv);
738-
err_card_detect:
739-
#if !defined(CONFIG_SDMMC_STM32_EMMC)
740-
stm32_sdmmc_card_detect_uninit(priv);
741-
#endif
742-
return err;
753+
return disk_access_register(&stm32_sdmmc_info);
743754
}
744755

745756
#if DT_NODE_HAS_STATUS_OKAY(DT_DRV_INST(0))

0 commit comments

Comments
 (0)