From 5f92c628742a51c77374897dc014e0119b9bc6c7 Mon Sep 17 00:00:00 2001 From: Petro Karashchenko Date: Sun, 13 Nov 2022 01:17:55 +0200 Subject: [PATCH] boards/cxd56xx/spresense: add fs automount driver for SD Card Signed-off-by: Petro Karashchenko --- arch/arm/src/cxd56xx/Kconfig | 2 + arch/arm/src/cxd56xx/cxd56_sdhci.c | 2 +- boards/arm/cxd56xx/spresense/Kconfig | 31 +- .../cxd56xx/spresense/configs/audio/defconfig | 2 - .../spresense/configs/camera/defconfig | 2 - .../configs/example_camera/defconfig | 2 - .../spresense/configs/example_lcd/defconfig | 2 - .../spresense/configs/fmsynth/defconfig | 2 - .../cxd56xx/spresense/configs/lcd/defconfig | 2 - .../cxd56xx/spresense/configs/lte/defconfig | 2 - .../cxd56xx/spresense/configs/mpy/defconfig | 2 - .../spresense/configs/nsh_automount/defconfig | 61 ++++ .../cxd56xx/spresense/configs/rndis/defconfig | 2 - .../spresense/configs/rndis_smp/defconfig | 2 - .../spresense/configs/usbmsc/defconfig | 2 - .../spresense/configs/usbnsh/defconfig | 2 - .../cxd56xx/spresense/configs/wifi/defconfig | 2 - .../spresense/configs/wifi_smp/defconfig | 2 - boards/arm/cxd56xx/spresense/include/board.h | 1 + .../spresense/include/cxd56_automount.h | 119 +++++++ .../cxd56xx/spresense/include/cxd56_sdcard.h | 14 + boards/arm/cxd56xx/spresense/src/Make.defs | 4 + .../cxd56xx/spresense/src/cxd56_automount.c | 322 ++++++++++++++++++ .../arm/cxd56xx/spresense/src/cxd56_bringup.c | 6 + .../arm/cxd56xx/spresense/src/cxd56_sdcard.c | 126 +++---- 25 files changed, 624 insertions(+), 92 deletions(-) create mode 100644 boards/arm/cxd56xx/spresense/configs/nsh_automount/defconfig create mode 100644 boards/arm/cxd56xx/spresense/include/cxd56_automount.h create mode 100644 boards/arm/cxd56xx/spresense/src/cxd56_automount.c diff --git a/arch/arm/src/cxd56xx/Kconfig b/arch/arm/src/cxd56xx/Kconfig index e845fc2bded90..9492d98a32bc5 100644 --- a/arch/arm/src/cxd56xx/Kconfig +++ b/arch/arm/src/cxd56xx/Kconfig @@ -1201,6 +1201,8 @@ menuconfig CXD56_SDIO default n select ARCH_HAVE_SDIO select SDIO_BLOCKSETUP + select MMCSD + select MMCSD_SDIO depends on SCHED_WORKQUEUE if CXD56_SDIO diff --git a/arch/arm/src/cxd56xx/cxd56_sdhci.c b/arch/arm/src/cxd56xx/cxd56_sdhci.c index 92b6b362769a9..65b4fe5e85ef0 100644 --- a/arch/arm/src/cxd56xx/cxd56_sdhci.c +++ b/arch/arm/src/cxd56xx/cxd56_sdhci.c @@ -3277,7 +3277,7 @@ struct sdio_dev_s *cxd56_sdhci_finalize(int slotno) /* SD clock disable */ - cxd56_sdio_clock(&(priv->dev), CLOCK_SDIO_DISABLED); + cxd56_sdio_clock(&priv->dev, CLOCK_SDIO_DISABLED); /* Power OFF for SDIO */ diff --git a/boards/arm/cxd56xx/spresense/Kconfig b/boards/arm/cxd56xx/spresense/Kconfig index 974f77cc162bf..fc0fe123a14ed 100644 --- a/boards/arm/cxd56xx/spresense/Kconfig +++ b/boards/arm/cxd56xx/spresense/Kconfig @@ -466,7 +466,7 @@ config SPRESENSE_EXTENSION present, then the SPresense will need to run at a higher power mode, selected by this option. -if SPRESENSE_EXTENSION +if SPRESENSE_EXTENSION config SDCARD_TXS02612 bool "SD Card TXS02612 port expander with voltage level translation" default y @@ -780,4 +780,33 @@ config CXD56_CAMERA_LATE_INITIALIZE The camera drivers can be initialized on an application code after system booted up by enabling this configuration switch. +config CXD56_SDCARD_AUTOMOUNT + bool "SDCARD automounter" + default n + depends on FS_AUTOMOUNTER && CXD56_SDIO + +if CXD56_SDCARD_AUTOMOUNT + +config CXD56_SDCARD_AUTOMOUNT_FSTYPE + string "SDCARD file system type" + default "vfat" + +config CXD56_SDCARD_AUTOMOUNT_BLKDEV + string "SDCARD block device" + default "/dev/mmcsd0" + +config CXD56_SDCARD_AUTOMOUNT_MOUNTPOINT + string "SDCARD mount point" + default "/mnt/sd0" + +config CXD56_SDCARD_AUTOMOUNT_DDELAY + int "SDCARD debounce delay (milliseconds)" + default 1000 + +config CXD56_SDCARD_AUTOMOUNT_UDELAY + int "SDCARD unmount retry delay (milliseconds)" + default 2000 + +endif # CXD56_SDCARD_AUTOMOUNT + endif diff --git a/boards/arm/cxd56xx/spresense/configs/audio/defconfig b/boards/arm/cxd56xx/spresense/configs/audio/defconfig index e21e870ec4e3e..195f91cf2b0fd 100644 --- a/boards/arm/cxd56xx/spresense/configs/audio/defconfig +++ b/boards/arm/cxd56xx/spresense/configs/audio/defconfig @@ -43,8 +43,6 @@ CONFIG_FS_SMARTFS=y CONFIG_HAVE_CXX=y CONFIG_HAVE_CXXINITIALIZE=y CONFIG_INIT_ENTRYPOINT="spresense_main" -CONFIG_MMCSD=y -CONFIG_MMCSD_SDIO=y CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_PARTITION=y CONFIG_MTD_SMART=y diff --git a/boards/arm/cxd56xx/spresense/configs/camera/defconfig b/boards/arm/cxd56xx/spresense/configs/camera/defconfig index 1211f937f8efb..c18342a311307 100644 --- a/boards/arm/cxd56xx/spresense/configs/camera/defconfig +++ b/boards/arm/cxd56xx/spresense/configs/camera/defconfig @@ -43,8 +43,6 @@ CONFIG_FS_SMARTFS=y CONFIG_HAVE_CXX=y CONFIG_HAVE_CXXINITIALIZE=y CONFIG_INIT_ENTRYPOINT="spresense_main" -CONFIG_MMCSD=y -CONFIG_MMCSD_SDIO=y CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_PARTITION=y CONFIG_MTD_SMART=y diff --git a/boards/arm/cxd56xx/spresense/configs/example_camera/defconfig b/boards/arm/cxd56xx/spresense/configs/example_camera/defconfig index 9e07ae690184b..a6c1eece02413 100644 --- a/boards/arm/cxd56xx/spresense/configs/example_camera/defconfig +++ b/boards/arm/cxd56xx/spresense/configs/example_camera/defconfig @@ -50,8 +50,6 @@ CONFIG_LCD=y CONFIG_LCD_ILI9340=y CONFIG_LCD_ILI9340_IFACE0=y CONFIG_LCD_ILI9340_IFACE0_RLANDSCAPE=y -CONFIG_MMCSD=y -CONFIG_MMCSD_SDIO=y CONFIG_MQ_MAXMSGSIZE=64 CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_PARTITION=y diff --git a/boards/arm/cxd56xx/spresense/configs/example_lcd/defconfig b/boards/arm/cxd56xx/spresense/configs/example_lcd/defconfig index 0015ab5dd1c8b..1972b273a45a2 100644 --- a/boards/arm/cxd56xx/spresense/configs/example_lcd/defconfig +++ b/boards/arm/cxd56xx/spresense/configs/example_lcd/defconfig @@ -58,8 +58,6 @@ CONFIG_INIT_ENTRYPOINT="spresense_main" CONFIG_LCD=y CONFIG_LCD_ILI9340=y CONFIG_LCD_ILI9340_IFACE0=y -CONFIG_MMCSD=y -CONFIG_MMCSD_SDIO=y CONFIG_MQ_MAXMSGSIZE=64 CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_PARTITION=y diff --git a/boards/arm/cxd56xx/spresense/configs/fmsynth/defconfig b/boards/arm/cxd56xx/spresense/configs/fmsynth/defconfig index ca717fb3c66e5..465a07fa3f973 100644 --- a/boards/arm/cxd56xx/spresense/configs/fmsynth/defconfig +++ b/boards/arm/cxd56xx/spresense/configs/fmsynth/defconfig @@ -49,8 +49,6 @@ CONFIG_FS_SMARTFS=y CONFIG_HAVE_CXX=y CONFIG_HAVE_CXXINITIALIZE=y CONFIG_INIT_ENTRYPOINT="spresense_main" -CONFIG_MMCSD=y -CONFIG_MMCSD_SDIO=y CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_PARTITION=y CONFIG_MTD_SMART=y diff --git a/boards/arm/cxd56xx/spresense/configs/lcd/defconfig b/boards/arm/cxd56xx/spresense/configs/lcd/defconfig index f808854b1640d..ba934a45fa1ba 100644 --- a/boards/arm/cxd56xx/spresense/configs/lcd/defconfig +++ b/boards/arm/cxd56xx/spresense/configs/lcd/defconfig @@ -49,8 +49,6 @@ CONFIG_INIT_ENTRYPOINT="spresense_main" CONFIG_LCD=y CONFIG_LCD_ILI9340=y CONFIG_LCD_ILI9340_IFACE0=y -CONFIG_MMCSD=y -CONFIG_MMCSD_SDIO=y CONFIG_MQ_MAXMSGSIZE=64 CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_PARTITION=y diff --git a/boards/arm/cxd56xx/spresense/configs/lte/defconfig b/boards/arm/cxd56xx/spresense/configs/lte/defconfig index 98a52ced1e46c..f888d4c6b9157 100644 --- a/boards/arm/cxd56xx/spresense/configs/lte/defconfig +++ b/boards/arm/cxd56xx/spresense/configs/lte/defconfig @@ -44,8 +44,6 @@ CONFIG_HAVE_CXXINITIALIZE=y CONFIG_INIT_ENTRYPOINT="spresense_main" CONFIG_MBEDTLS_APPS=y CONFIG_MBEDTLS_VERSION="2.28.0" -CONFIG_MMCSD=y -CONFIG_MMCSD_SDIO=y CONFIG_MODEM=y CONFIG_MODEM_ALT1250=y CONFIG_MTD_BYTE_WRITE=y diff --git a/boards/arm/cxd56xx/spresense/configs/mpy/defconfig b/boards/arm/cxd56xx/spresense/configs/mpy/defconfig index ed773a280ab28..3c9243d06b71f 100644 --- a/boards/arm/cxd56xx/spresense/configs/mpy/defconfig +++ b/boards/arm/cxd56xx/spresense/configs/mpy/defconfig @@ -53,8 +53,6 @@ CONFIG_FS_SMARTFS=y CONFIG_HAVE_CXX=y CONFIG_HAVE_CXXINITIALIZE=y CONFIG_INIT_ENTRYPOINT="spresense_main" -CONFIG_MMCSD=y -CONFIG_MMCSD_SDIO=y CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_PARTITION=y CONFIG_MTD_SMART=y diff --git a/boards/arm/cxd56xx/spresense/configs/nsh_automount/defconfig b/boards/arm/cxd56xx/spresense/configs/nsh_automount/defconfig new file mode 100644 index 0000000000000..ebffd808ef2a1 --- /dev/null +++ b/boards/arm/cxd56xx/spresense/configs/nsh_automount/defconfig @@ -0,0 +1,61 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_CXD56_I2C0_SCUSEQ is not set +# CONFIG_STANDARD_SERIAL is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="spresense" +CONFIG_ARCH_BOARD_COMMON=y +CONFIG_ARCH_BOARD_SPRESENSE=y +CONFIG_ARCH_CHIP="cxd56xx" +CONFIG_ARCH_CHIP_CXD56XX=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARMV7M_USEBASEPRI=y +CONFIG_BOARD_LOOPSPERMSEC=5434 +CONFIG_BOOT_RUNFROMISRAM=y +CONFIG_BUILTIN=y +CONFIG_CXD56_BINARY=y +CONFIG_CXD56_I2C0=y +CONFIG_CXD56_I2C=y +CONFIG_CXD56_SDCARD_AUTOMOUNT=y +CONFIG_CXD56_SDIO=y +CONFIG_CXD56_SPI4=y +CONFIG_CXD56_SPI5=y +CONFIG_CXD56_SPI=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_FAT_LCNAMES=y +CONFIG_FAT_LFN=y +CONFIG_FS_AUTOMOUNTER=y +CONFIG_FS_AUTOMOUNTER_DRIVER=y +CONFIG_FS_FAT=y +CONFIG_FS_PROCFS=y +CONFIG_FS_PROCFS_REGISTER=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_INIT_ENTRYPOINT="spresense_main" +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=1572864 +CONFIG_RAM_START=0x0d000000 +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_RR_INTERVAL=200 +CONFIG_RTC=y +CONFIG_RTC_DRIVER=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_SPI=y +CONFIG_SPRESENSE_EXTENSION=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_SYSTEM_CLE=y +CONFIG_SYSTEM_NSH=y +CONFIG_UART1_SERIAL_CONSOLE=y +CONFIG_WQUEUE_NOTIFIER=y diff --git a/boards/arm/cxd56xx/spresense/configs/rndis/defconfig b/boards/arm/cxd56xx/spresense/configs/rndis/defconfig index 6ce79e935e975..12a40dbc53a08 100644 --- a/boards/arm/cxd56xx/spresense/configs/rndis/defconfig +++ b/boards/arm/cxd56xx/spresense/configs/rndis/defconfig @@ -68,8 +68,6 @@ CONFIG_LIBC_EXECFUNCS=y CONFIG_MEMCPY_VIK=y CONFIG_MEMSET_64BIT=y CONFIG_MEMSET_OPTSPEED=y -CONFIG_MMCSD=y -CONFIG_MMCSD_SDIO=y CONFIG_MQ_MAXMSGSIZE=64 CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_PARTITION=y diff --git a/boards/arm/cxd56xx/spresense/configs/rndis_smp/defconfig b/boards/arm/cxd56xx/spresense/configs/rndis_smp/defconfig index c1e8b6753b8b3..83dcb662917dc 100644 --- a/boards/arm/cxd56xx/spresense/configs/rndis_smp/defconfig +++ b/boards/arm/cxd56xx/spresense/configs/rndis_smp/defconfig @@ -70,8 +70,6 @@ CONFIG_LIBC_EXECFUNCS=y CONFIG_MEMCPY_VIK=y CONFIG_MEMSET_64BIT=y CONFIG_MEMSET_OPTSPEED=y -CONFIG_MMCSD=y -CONFIG_MMCSD_SDIO=y CONFIG_MQ_MAXMSGSIZE=64 CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_PARTITION=y diff --git a/boards/arm/cxd56xx/spresense/configs/usbmsc/defconfig b/boards/arm/cxd56xx/spresense/configs/usbmsc/defconfig index b6bfebece8928..47275da5f3e07 100644 --- a/boards/arm/cxd56xx/spresense/configs/usbmsc/defconfig +++ b/boards/arm/cxd56xx/spresense/configs/usbmsc/defconfig @@ -47,8 +47,6 @@ CONFIG_FS_SMARTFS=y CONFIG_HAVE_CXX=y CONFIG_HAVE_CXXINITIALIZE=y CONFIG_INIT_ENTRYPOINT="spresense_main" -CONFIG_MMCSD=y -CONFIG_MMCSD_SDIO=y CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_PARTITION=y CONFIG_MTD_SMART=y diff --git a/boards/arm/cxd56xx/spresense/configs/usbnsh/defconfig b/boards/arm/cxd56xx/spresense/configs/usbnsh/defconfig index 16076a35cdd54..41ca505e6c5f0 100644 --- a/boards/arm/cxd56xx/spresense/configs/usbnsh/defconfig +++ b/boards/arm/cxd56xx/spresense/configs/usbnsh/defconfig @@ -40,8 +40,6 @@ CONFIG_FS_SMARTFS=y CONFIG_HAVE_CXX=y CONFIG_HAVE_CXXINITIALIZE=y CONFIG_INIT_ENTRYPOINT="spresense_main" -CONFIG_MMCSD=y -CONFIG_MMCSD_SDIO=y CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_PARTITION=y CONFIG_MTD_SMART=y diff --git a/boards/arm/cxd56xx/spresense/configs/wifi/defconfig b/boards/arm/cxd56xx/spresense/configs/wifi/defconfig index db1329e16dcb5..7ca965a5999a2 100644 --- a/boards/arm/cxd56xx/spresense/configs/wifi/defconfig +++ b/boards/arm/cxd56xx/spresense/configs/wifi/defconfig @@ -82,8 +82,6 @@ CONFIG_LIBC_EXECFUNCS=y CONFIG_MEMCPY_VIK=y CONFIG_MEMSET_64BIT=y CONFIG_MEMSET_OPTSPEED=y -CONFIG_MMCSD=y -CONFIG_MMCSD_SDIO=y CONFIG_MQ_MAXMSGSIZE=64 CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_PARTITION=y diff --git a/boards/arm/cxd56xx/spresense/configs/wifi_smp/defconfig b/boards/arm/cxd56xx/spresense/configs/wifi_smp/defconfig index 90b098a44d39f..d8733f66ab7f4 100644 --- a/boards/arm/cxd56xx/spresense/configs/wifi_smp/defconfig +++ b/boards/arm/cxd56xx/spresense/configs/wifi_smp/defconfig @@ -85,8 +85,6 @@ CONFIG_LIBC_EXECFUNCS=y CONFIG_MEMCPY_VIK=y CONFIG_MEMSET_64BIT=y CONFIG_MEMSET_OPTSPEED=y -CONFIG_MMCSD=y -CONFIG_MMCSD_SDIO=y CONFIG_MQ_MAXMSGSIZE=64 CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_PARTITION=y diff --git a/boards/arm/cxd56xx/spresense/include/board.h b/boards/arm/cxd56xx/spresense/include/board.h index a1df82efd4990..39d7e1b7ea9a3 100644 --- a/boards/arm/cxd56xx/spresense/include/board.h +++ b/boards/arm/cxd56xx/spresense/include/board.h @@ -41,6 +41,7 @@ #include "cxd56_i2cdev.h" #include "cxd56_spidev.h" #include "cxd56_sdcard.h" +#include "cxd56_automount.h" #include "cxd56_wdt.h" #include "cxd56_gpioif.h" diff --git a/boards/arm/cxd56xx/spresense/include/cxd56_automount.h b/boards/arm/cxd56xx/spresense/include/cxd56_automount.h new file mode 100644 index 0000000000000..df2f75c009f8e --- /dev/null +++ b/boards/arm/cxd56xx/spresense/include/cxd56_automount.h @@ -0,0 +1,119 @@ +/**************************************************************************** + * boards/arm/cxd56xx/spresense/include/cxd56_automount.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __BOARDS_ARM_CXD56XX_SPRESENSE_INCLUDE_CXD56_AUTOMOUNT_H +#define __BOARDS_ARM_CXD56XX_SPRESENSE_INCLUDE_CXD56_AUTOMOUNT_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_CXD56_SDCARD_AUTOMOUNT_FSTYPE +# define CONFIG_CXD56_SDCARD_AUTOMOUNT_FSTYPE "vfat" +#endif + +#ifndef CONFIG_CXD56_SDCARD_AUTOMOUNT_BLKDEV +# define CONFIG_CXD56_SDCARD_AUTOMOUNT_BLKDEV "/dev/mmcds0" +#endif + +#ifndef CONFIG_CXD56_SDCARD_AUTOMOUNT_MOUNTPOINT +# define CONFIG_CXD56_SDCARD_AUTOMOUNT_MOUNTPOINT "/mnt/sd0" +#endif + +#ifndef CONFIG_CXD56_SDCARD_AUTOMOUNT_DDELAY +# define CONFIG_CXD56_SDCARD_AUTOMOUNT_DDELAY 1000 +#endif + +#ifndef CONFIG_CXD56_SDCARD_AUTOMOUNT_UDELAY +# define CONFIG_CXD56_SDCARD_AUTOMOUNT_UDELAY 2000 +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions Definitions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_automount_initialize + * + * Description: + * Configure auto-mounters for each enable and so configured SDCARD + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void board_automount_initialize(void); + +/**************************************************************************** + * Name: board_automount_event + * + * Description: + * The HSMCI card detection logic has detected an insertion or removal + * event. It has already scheduled the MMC/SD block driver operations. + * Now we need to schedule the auto-mount event which will occur with a + * substantial delay to make sure that everything has settle down. + * + * Input Parameters: + * slotno - Identifies the HSMCI0 slot: HSMCI0 or HSMCI1_SLOTNO. + * There is a terminology problem here: Each HSMCI supports two slots, + * slot A and slot B. Only slot A is used. So this is not a really a + * slot, but an HSCMI peripheral number. + * inserted - True if the card is inserted in the slot. False otherwise. + * + * Returned Value: + * None + * + * Assumptions: + * Interrupts are disabled. + * + ****************************************************************************/ + +void board_automount_event(int slotno, bool inserted); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __BOARDS_ARM_CXD56XX_SPRESENSE_INCLUDE_CXD56_AUTOMOUNT_H */ diff --git a/boards/arm/cxd56xx/spresense/include/cxd56_sdcard.h b/boards/arm/cxd56xx/spresense/include/cxd56_sdcard.h index 0b8a3f4ab7f08..fa5fb9e3bd88e 100644 --- a/boards/arm/cxd56xx/spresense/include/cxd56_sdcard.h +++ b/boards/arm/cxd56xx/spresense/include/cxd56_sdcard.h @@ -131,6 +131,20 @@ void board_sdcard_set_high_voltage(void); void board_sdcard_set_low_voltage(void); +/**************************************************************************** + * Name: board_sdcard_inserted + * + * Description: + * Check if a card is inserted into the selected SD Card slot + * + ****************************************************************************/ + +#ifdef CONFIG_MMCSD_HAVE_CARDDETECT +bool board_sdcard_inserted(int slotno); +#else +# define board_sdcard_inserted(slotno) true +#endif + /**************************************************************************** * Name: board_sdcard_set_state_cb * diff --git a/boards/arm/cxd56xx/spresense/src/Make.defs b/boards/arm/cxd56xx/spresense/src/Make.defs index f9983fcda20ca..b13f155bd14fb 100644 --- a/boards/arm/cxd56xx/spresense/src/Make.defs +++ b/boards/arm/cxd56xx/spresense/src/Make.defs @@ -59,6 +59,10 @@ ifeq ($(CONFIG_CXD56_SDIO),y) CSRCS += cxd56_sdcard.c endif +ifeq ($(CONFIG_CXD56_SDCARD_AUTOMOUNT),y) +CSRCS += cxd56_automount.c +endif + ifeq ($(CONFIG_CXD56_GAUGE),y) CSRCS += cxd56_gauge.c endif diff --git a/boards/arm/cxd56xx/spresense/src/cxd56_automount.c b/boards/arm/cxd56xx/spresense/src/cxd56_automount.c new file mode 100644 index 0000000000000..110c200bc46f2 --- /dev/null +++ b/boards/arm/cxd56xx/spresense/src/cxd56_automount.c @@ -0,0 +1,322 @@ +/**************************************************************************** + * boards/arm/cxd56xx/spresense/src/cxd56_automount.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#if defined(CONFIG_FS_AUTOMOUNTER_DEBUG) && !defined(CONFIG_DEBUG_FS) +# define CONFIG_DEBUG_FS 1 +#endif + +#include +#include + +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure represents the changeable state of the automounter */ + +struct cxd56_automount_state_s +{ + volatile automount_handler_t handler; /* Upper half handler */ + void *arg; /* Handler argument */ + bool enable; /* Fake interrupt enable */ + bool pending; /* Set if there an event while disabled */ +}; + +/* This structure represents the static configuration of an automounter */ + +struct cxd56_automount_config_s +{ + /* This must be first thing in structure so that we can simply cast from + * struct automount_lower_s to struct cxd56_automount_config_s + */ + + struct automount_lower_s lower; /* Publicly visible part */ + struct cxd56_automount_state_s *state; /* Changeable state */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int sdcard_attach(const struct automount_lower_s *lower, + automount_handler_t isr, void *arg); +static void sdcard_enable(const struct automount_lower_s *lower, + bool enable); +static bool sdcard_inserted(const struct automount_lower_s *lower); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_CXD56_SDCARD_AUTOMOUNT +static struct cxd56_automount_state_s g_sdcard0state; +static const struct cxd56_automount_config_s g_sdcard0config = +{ + .lower = + { + .fstype = CONFIG_CXD56_SDCARD_AUTOMOUNT_FSTYPE, + .blockdev = CONFIG_CXD56_SDCARD_AUTOMOUNT_BLKDEV, + .mountpoint = CONFIG_CXD56_SDCARD_AUTOMOUNT_MOUNTPOINT, + .ddelay = MSEC2TICK(CONFIG_CXD56_SDCARD_AUTOMOUNT_DDELAY), + .udelay = MSEC2TICK(CONFIG_CXD56_SDCARD_AUTOMOUNT_UDELAY), + .attach = sdcard_attach, + .enable = sdcard_enable, + .inserted = sdcard_inserted + }, + .state = &g_sdcard0state +}; +#endif /* CONFIG_CXD56_SDCARD_AUTOMOUNT */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sdcard_attach + * + * Description: + * Attach a new SDCARD event handler + * + * Input Parameters: + * lower - An instance of the auto-mounter lower half state structure + * isr - The new event handler to be attach + * arg - Client data to be provided when the event handler is invoked. + * + * Returned Value: + * Always returns OK + * + ****************************************************************************/ + +static int sdcard_attach(const struct automount_lower_s *lower, + automount_handler_t isr, void *arg) +{ + const struct cxd56_automount_config_s *config; + struct cxd56_automount_state_s *state; + + /* Recover references to our structure */ + + config = (struct cxd56_automount_config_s *)lower; + DEBUGASSERT(config && config->state); + + state = config->state; + + /* Save the new handler info (clearing the handler first to eliminate race + * conditions). + */ + + state->handler = NULL; + state->pending = false; + state->arg = arg; + state->handler = isr; + return OK; +} + +/**************************************************************************** + * Name: sdcard_enable + * + * Description: + * Enable card insertion/removal event detection + * + * Input Parameters: + * lower - An instance of the auto-mounter lower half state structure + * enable - True: enable event detection; False: disable + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sdcard_enable(const struct automount_lower_s *lower, + bool enable) +{ + const struct cxd56_automount_config_s *config; + struct cxd56_automount_state_s *state; + irqstate_t flags; + + /* Recover references to our structure */ + + config = (struct cxd56_automount_config_s *)lower; + DEBUGASSERT(config && config->state); + + state = config->state; + + /* Save the fake enable setting */ + + flags = enter_critical_section(); + state->enable = enable; + + /* Did an interrupt occur while interrupts were disabled? */ + + if (enable && state->pending) + { + /* Yes.. perform the fake interrupt if the interrupt is attached */ + + if (state->handler) + { + bool inserted = board_sdcard_inserted(0); + state->handler(&config->lower, state->arg, inserted); + } + + state->pending = false; + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: sdcard_inserted + * + * Description: + * Check if a card is inserted into the slot. + * + * Input Parameters: + * lower - An instance of the auto-mounter lower half state structure + * + * Returned Value: + * True if the card is inserted; False otherwise + * + ****************************************************************************/ + +static bool sdcard_inserted(const struct automount_lower_s *lower) +{ + const struct cxd56_automount_config_s *config; + + config = (struct cxd56_automount_config_s *)lower; + DEBUGASSERT(config && config->state); + + return board_sdcard_inserted(0); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_automount_initialize + * + * Description: + * Configure auto-mounters for each enable and so configured SDCARD + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void board_automount_initialize(void) +{ + void *handle; + + finfo("Initializing automounter(s)\n"); + +#ifdef CONFIG_CXD56_SDCARD_AUTOMOUNT + /* Initialize the SDCARD auto-mounter */ + + handle = automount_initialize(&g_sdcard0config.lower); + if (handle == NULL) + { + ferr("ERROR: Failed to initialize auto-mounter for SDCARD\n"); + } +#endif /* CONFIG_CXD56_SDCARD_AUTOMOUNT */ +} + +/**************************************************************************** + * Name: board_automount_event + * + * Description: + * The SDCARD card detection logic has detected an insertion or removal + * event. + * It has already scheduled the MMC/SD block driver operations. + * Now we need to schedule the auto-mount event which will occur with a + * substantial delay to make sure that everything has settle down. + * + * Input Parameters: + * slotno - Identifies the SDCARD slot: Only slot 0 is used. + * inserted - True if the card is inserted in the slot. False otherwise. + * + * Returned Value: + * None + * + * Assumptions: + * Interrupts are disabled. + * + ****************************************************************************/ + +void board_automount_event(int slotno, bool inserted) +{ + const struct cxd56_automount_config_s *config; + struct cxd56_automount_state_s *state; + +#ifdef CONFIG_CXD56_SDCARD_AUTOMOUNT + /* Is this a change in the SDCARD insertion state? */ + + if (slotno == 0) + { + /* Yes.. Select the SDCARD automounter */ + + config = &g_sdcard0config; + state = &g_sdcard0state; + } + else +#endif /* CONFIG_CXD56_SDCARD_AUTOMOUNT */ + { + ferr("ERROR: Unsupported SDCARD%d\n", slotno); + return; + } + + /* Is the auto-mounter interrupt attached? */ + + if (state->handler) + { + /* Yes.. Have we been asked to hold off interrupts? */ + + if (!state->enable) + { + /* Yes.. just remember that there is a pending interrupt. We will + * deliver the interrupt when interrupts are "re-enabled." + */ + + state->pending = true; + } + else + { + /* No.. forward the event to the handler */ + + state->handler(&config->lower, state->arg, inserted); + } + } +} diff --git a/boards/arm/cxd56xx/spresense/src/cxd56_bringup.c b/boards/arm/cxd56xx/spresense/src/cxd56_bringup.c index c2ab78de1aef6..43b61ac0d1915 100644 --- a/boards/arm/cxd56xx/spresense/src/cxd56_bringup.c +++ b/boards/arm/cxd56xx/spresense/src/cxd56_bringup.c @@ -434,6 +434,12 @@ int cxd56_bringup(void) } #endif +#ifdef CONFIG_CXD56_SDCARD_AUTOMOUNT + /* Initialize the auto-mounter */ + + board_automount_initialize(); +#endif + #ifdef CONFIG_CPUFREQ_RELEASE_LOCK /* Enable dynamic clock control and CPU clock down for power saving */ diff --git a/boards/arm/cxd56xx/spresense/src/cxd56_sdcard.c b/boards/arm/cxd56xx/spresense/src/cxd56_sdcard.c index 3701fb8a1d1ae..fc9afa9406d9b 100644 --- a/boards/arm/cxd56xx/spresense/src/cxd56_sdcard.c +++ b/boards/arm/cxd56xx/spresense/src/cxd56_sdcard.c @@ -69,7 +69,9 @@ struct cxd56_sdhci_state_s { struct sdio_dev_s *sdhci; /* R/W device handle */ bool initialized; /* TRUE: SDHCI block driver is initialized */ +#ifdef CONFIG_MMCSD_HAVE_CARDDETECT bool inserted; /* TRUE: card is inserted */ +#endif void (*cb)(bool); /* Callback function pointer to application */ }; @@ -117,7 +119,7 @@ static void board_sdcard_enable(void *arg) finfo("Initializing SDHC slot 0\n"); g_sdhci.sdhci = cxd56_sdhci_initialize(0); - if (!g_sdhci.sdhci) + if (g_sdhci.sdhci == NULL) { _err("ERROR: Failed to initialize SDHC slot 0\n"); goto release_frequency_lock; @@ -135,7 +137,7 @@ static void board_sdcard_enable(void *arg) if (ret != OK) { _err("ERROR: Failed to bind SDHC to the MMC/SD driver: %d\n", - ret); + ret); goto release_frequency_lock; } @@ -146,6 +148,7 @@ static void board_sdcard_enable(void *arg) cxd56_sdhci_mediachange(g_sdhci.sdhci); +#ifndef CONFIG_CXD56_SDCARD_AUTOMOUNT if (nx_stat("/dev/mmcsd0", &stat_sdio, 1) == 0) { if (S_ISBLK(stat_sdio.st_mode)) @@ -165,16 +168,23 @@ static void board_sdcard_enable(void *arg) } } - g_sdhci.initialized = true; - /* Callback to application to notice card is inserted */ if (g_sdhci.cb != NULL) { g_sdhci.cb(true); } +#endif /* CONFIG_CXD56_SDCARD_AUTOMOUNT */ + + g_sdhci.initialized = true; } +#ifdef CONFIG_CXD56_SDCARD_AUTOMOUNT + /* Let the automounter know about the insertion event */ + + board_automount_event(0, board_sdcard_inserted(0)); +#endif /* CONFIG_CXD56_SDCARD_AUTOMOUNT */ + release_frequency_lock: /* Release frequency lock */ @@ -192,10 +202,11 @@ static void board_sdcard_enable(void *arg) static void board_sdcard_disable(void *arg) { - int ret; - if (g_sdhci.initialized) { +#ifndef CONFIG_CXD56_SDCARD_AUTOMOUNT + int ret; + /* un-mount */ ret = nx_umount2("/mnt/sd0", 0); @@ -204,53 +215,37 @@ static void board_sdcard_disable(void *arg) ferr("ERROR: Failed to unmount the SD Card: %d\n", ret); } - /* Report the new state to the SDIO driver */ - - cxd56_sdhci_mediachange(g_sdhci.sdhci); - - cxd56_sdhci_finalize(0); - - g_sdhci.initialized = false; - /* Callback to application to notice card is ejected */ if (g_sdhci.cb != NULL) { g_sdhci.cb(false); } - } -} +#endif /* CONFIG_CXD56_SDCARD_AUTOMOUNT */ -#ifdef CONFIG_MMCSD_HAVE_CARDDETECT -/**************************************************************************** - * Name: board_sdcard_inserted - * - * Description: - * Check if a card is inserted into the selected SDHCI slot - * - ****************************************************************************/ + /* Report the new state to the SDIO driver */ -static bool board_sdcard_inserted(int slotno) -{ - bool removed; + cxd56_sdhci_mediachange(g_sdhci.sdhci); - /* Get the state of the GPIO pin */ + cxd56_sdhci_finalize(0); - removed = cxd56_gpio_read(PIN_SDIO_CD); - finfo("Slot %d inserted: %s\n", slotno, removed ? "NO" : "YES"); + g_sdhci.initialized = false; + } - return !removed; +#ifdef CONFIG_CXD56_SDCARD_AUTOMOUNT + /* Let the automounter know about the insertion event */ + + board_automount_event(0, board_sdcard_inserted(0)); +#endif /* CONFIG_CXD56_SDCARD_AUTOMOUNT */ } +#ifdef CONFIG_MMCSD_HAVE_CARDDETECT /**************************************************************************** * Name: board_sdcard_detect_int * * Description: * Card detect interrupt handler * - * TODO: Any way to automatically moun/unmount filesystem based on card - * detect status? Yes... send a message or signal to an application. - * ****************************************************************************/ static int board_sdcard_detect_int(int irq, void *context, void *arg) @@ -309,15 +304,6 @@ static int board_sdcard_detect_int(int irq, void *context, void *arg) board_sdcard_disable(NULL); } } - - /* Re-configure Interrupt pin */ - - cxd56_gpioint_config(PIN_SDIO_CD, - inserted ? - GPIOINT_PSEUDO_EDGE_RISE : - GPIOINT_PSEUDO_EDGE_FALL, - board_sdcard_detect_int, - NULL); } return OK; @@ -358,23 +344,20 @@ int board_sdcard_initialize(void) /* Configure Interrupt pin with internal pull-up */ cxd56_pin_config(PINCONF_SDIO_CD_GPIO); - ret = cxd56_gpioint_config(PIN_SDIO_CD, - GPIOINT_PSEUDO_EDGE_FALL, - board_sdcard_detect_int, - NULL); - if (ret < 0) - { - _err("ERROR: Failed to configure GPIO int.\n"); - } + + /* Handle the case when SD card is already inserted */ + + board_sdcard_detect_int(PIN_SDIO_CD, NULL, NULL); + + /* Configure Interrupt pin with internal pull-up */ + + cxd56_gpioint_config(PIN_SDIO_CD, GPIOINT_PSEUDO_EDGE_BOTH, + board_sdcard_detect_int, NULL); /* Enabling Interrupt */ cxd56_gpioint_enable(PIN_SDIO_CD); #else - /* Initialize Card insert status */ - - g_sdhci.inserted = true; - /* Enable SDC */ board_sdcard_enable(NULL); @@ -397,19 +380,16 @@ int board_sdcard_finalize(void) /* At first, Disable interrupt of the card detection */ - if (g_sdhci.inserted) - { - board_sdcard_disable(NULL); - } - - g_sdhci.inserted = false; - #ifdef CONFIG_MMCSD_HAVE_CARDDETECT /* Disabling Interrupt */ cxd56_gpioint_disable(PIN_SDIO_CD); + + g_sdhci.inserted = false; #endif + board_sdcard_disable(NULL); + /* Disable SDIO pin configuration */ CXD56_PIN_CONFIGS(PINCONFS_SDIOA_GPIO); @@ -531,6 +511,28 @@ void board_sdcard_set_low_voltage(void) { } +#ifdef CONFIG_MMCSD_HAVE_CARDDETECT +/**************************************************************************** + * Name: board_sdcard_inserted + * + * Description: + * Check if a card is inserted into the selected SDHCI slot + * + ****************************************************************************/ + +bool board_sdcard_inserted(int slotno) +{ + bool removed; + + /* Get the state of the GPIO pin */ + + removed = cxd56_gpio_read(PIN_SDIO_CD); + finfo("Slot %d inserted: %s\n", slotno, removed ? "NO" : "YES"); + + return !removed; +} +#endif + /**************************************************************************** * Name: board_sdcard_set_state_cb *