boards/cxd56xx/spresense: add fs automount driver for SD Card

Signed-off-by: Petro Karashchenko <petro.karashchenko@gmail.com>
This commit is contained in:
Petro Karashchenko 2022-11-13 01:17:55 +02:00 committed by Masayuki Ishikawa
parent 78248183aa
commit 5f92c62874
25 changed files with 626 additions and 94 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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 */

View File

@ -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
*

View File

@ -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

View File

@ -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 <nuttx/config.h>
#if defined(CONFIG_FS_AUTOMOUNTER_DEBUG) && !defined(CONFIG_DEBUG_FS)
# define CONFIG_DEBUG_FS 1
#endif
#include <assert.h>
#include <debug.h>
#include <arch/board/board.h>
#include <nuttx/irq.h>
#include <nuttx/clock.h>
#include <nuttx/fs/automount.h>
/****************************************************************************
* 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);
}
}
}

View File

@ -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 */

View File

@ -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 @@ release_frequency_lock:
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,6 +215,14 @@ static void board_sdcard_disable(void *arg)
ferr("ERROR: Failed to unmount the SD Card: %d\n", ret);
}
/* Callback to application to notice card is ejected */
if (g_sdhci.cb != NULL)
{
g_sdhci.cb(false);
}
#endif /* CONFIG_CXD56_SDCARD_AUTOMOUNT */
/* Report the new state to the SDIO driver */
cxd56_sdhci_mediachange(g_sdhci.sdhci);
@ -211,46 +230,22 @@ static void board_sdcard_disable(void *arg)
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);
}
}
#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_inserted
*
* Description:
* Check if a card is inserted into the selected SDHCI slot
*
****************************************************************************/
static 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;
}
/****************************************************************************
* 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
*