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
+2
View File
@@ -1201,6 +1201,8 @@ menuconfig CXD56_SDIO
default n default n
select ARCH_HAVE_SDIO select ARCH_HAVE_SDIO
select SDIO_BLOCKSETUP select SDIO_BLOCKSETUP
select MMCSD
select MMCSD_SDIO
depends on SCHED_WORKQUEUE depends on SCHED_WORKQUEUE
if CXD56_SDIO if CXD56_SDIO
+1 -1
View File
@@ -3277,7 +3277,7 @@ struct sdio_dev_s *cxd56_sdhci_finalize(int slotno)
/* SD clock disable */ /* SD clock disable */
cxd56_sdio_clock(&(priv->dev), CLOCK_SDIO_DISABLED); cxd56_sdio_clock(&priv->dev, CLOCK_SDIO_DISABLED);
/* Power OFF for SDIO */ /* Power OFF for SDIO */
+30 -1
View File
@@ -466,7 +466,7 @@ config SPRESENSE_EXTENSION
present, then the SPresense will need to run at a higher power mode, present, then the SPresense will need to run at a higher power mode,
selected by this option. selected by this option.
if SPRESENSE_EXTENSION if SPRESENSE_EXTENSION
config SDCARD_TXS02612 config SDCARD_TXS02612
bool "SD Card TXS02612 port expander with voltage level translation" bool "SD Card TXS02612 port expander with voltage level translation"
default y 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 The camera drivers can be initialized on an application code after system booted up
by enabling this configuration switch. 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 endif
@@ -43,8 +43,6 @@ CONFIG_FS_SMARTFS=y
CONFIG_HAVE_CXX=y CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_INIT_ENTRYPOINT="spresense_main" CONFIG_INIT_ENTRYPOINT="spresense_main"
CONFIG_MMCSD=y
CONFIG_MMCSD_SDIO=y
CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_BYTE_WRITE=y
CONFIG_MTD_PARTITION=y CONFIG_MTD_PARTITION=y
CONFIG_MTD_SMART=y CONFIG_MTD_SMART=y
@@ -43,8 +43,6 @@ CONFIG_FS_SMARTFS=y
CONFIG_HAVE_CXX=y CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_INIT_ENTRYPOINT="spresense_main" CONFIG_INIT_ENTRYPOINT="spresense_main"
CONFIG_MMCSD=y
CONFIG_MMCSD_SDIO=y
CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_BYTE_WRITE=y
CONFIG_MTD_PARTITION=y CONFIG_MTD_PARTITION=y
CONFIG_MTD_SMART=y CONFIG_MTD_SMART=y
@@ -50,8 +50,6 @@ CONFIG_LCD=y
CONFIG_LCD_ILI9340=y CONFIG_LCD_ILI9340=y
CONFIG_LCD_ILI9340_IFACE0=y CONFIG_LCD_ILI9340_IFACE0=y
CONFIG_LCD_ILI9340_IFACE0_RLANDSCAPE=y CONFIG_LCD_ILI9340_IFACE0_RLANDSCAPE=y
CONFIG_MMCSD=y
CONFIG_MMCSD_SDIO=y
CONFIG_MQ_MAXMSGSIZE=64 CONFIG_MQ_MAXMSGSIZE=64
CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_BYTE_WRITE=y
CONFIG_MTD_PARTITION=y CONFIG_MTD_PARTITION=y
@@ -58,8 +58,6 @@ CONFIG_INIT_ENTRYPOINT="spresense_main"
CONFIG_LCD=y CONFIG_LCD=y
CONFIG_LCD_ILI9340=y CONFIG_LCD_ILI9340=y
CONFIG_LCD_ILI9340_IFACE0=y CONFIG_LCD_ILI9340_IFACE0=y
CONFIG_MMCSD=y
CONFIG_MMCSD_SDIO=y
CONFIG_MQ_MAXMSGSIZE=64 CONFIG_MQ_MAXMSGSIZE=64
CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_BYTE_WRITE=y
CONFIG_MTD_PARTITION=y CONFIG_MTD_PARTITION=y
@@ -49,8 +49,6 @@ CONFIG_FS_SMARTFS=y
CONFIG_HAVE_CXX=y CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_INIT_ENTRYPOINT="spresense_main" CONFIG_INIT_ENTRYPOINT="spresense_main"
CONFIG_MMCSD=y
CONFIG_MMCSD_SDIO=y
CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_BYTE_WRITE=y
CONFIG_MTD_PARTITION=y CONFIG_MTD_PARTITION=y
CONFIG_MTD_SMART=y CONFIG_MTD_SMART=y
@@ -49,8 +49,6 @@ CONFIG_INIT_ENTRYPOINT="spresense_main"
CONFIG_LCD=y CONFIG_LCD=y
CONFIG_LCD_ILI9340=y CONFIG_LCD_ILI9340=y
CONFIG_LCD_ILI9340_IFACE0=y CONFIG_LCD_ILI9340_IFACE0=y
CONFIG_MMCSD=y
CONFIG_MMCSD_SDIO=y
CONFIG_MQ_MAXMSGSIZE=64 CONFIG_MQ_MAXMSGSIZE=64
CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_BYTE_WRITE=y
CONFIG_MTD_PARTITION=y CONFIG_MTD_PARTITION=y
@@ -44,8 +44,6 @@ CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_INIT_ENTRYPOINT="spresense_main" CONFIG_INIT_ENTRYPOINT="spresense_main"
CONFIG_MBEDTLS_APPS=y CONFIG_MBEDTLS_APPS=y
CONFIG_MBEDTLS_VERSION="2.28.0" CONFIG_MBEDTLS_VERSION="2.28.0"
CONFIG_MMCSD=y
CONFIG_MMCSD_SDIO=y
CONFIG_MODEM=y CONFIG_MODEM=y
CONFIG_MODEM_ALT1250=y CONFIG_MODEM_ALT1250=y
CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_BYTE_WRITE=y
@@ -53,8 +53,6 @@ CONFIG_FS_SMARTFS=y
CONFIG_HAVE_CXX=y CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_INIT_ENTRYPOINT="spresense_main" CONFIG_INIT_ENTRYPOINT="spresense_main"
CONFIG_MMCSD=y
CONFIG_MMCSD_SDIO=y
CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_BYTE_WRITE=y
CONFIG_MTD_PARTITION=y CONFIG_MTD_PARTITION=y
CONFIG_MTD_SMART=y CONFIG_MTD_SMART=y
@@ -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
@@ -68,8 +68,6 @@ CONFIG_LIBC_EXECFUNCS=y
CONFIG_MEMCPY_VIK=y CONFIG_MEMCPY_VIK=y
CONFIG_MEMSET_64BIT=y CONFIG_MEMSET_64BIT=y
CONFIG_MEMSET_OPTSPEED=y CONFIG_MEMSET_OPTSPEED=y
CONFIG_MMCSD=y
CONFIG_MMCSD_SDIO=y
CONFIG_MQ_MAXMSGSIZE=64 CONFIG_MQ_MAXMSGSIZE=64
CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_BYTE_WRITE=y
CONFIG_MTD_PARTITION=y CONFIG_MTD_PARTITION=y
@@ -70,8 +70,6 @@ CONFIG_LIBC_EXECFUNCS=y
CONFIG_MEMCPY_VIK=y CONFIG_MEMCPY_VIK=y
CONFIG_MEMSET_64BIT=y CONFIG_MEMSET_64BIT=y
CONFIG_MEMSET_OPTSPEED=y CONFIG_MEMSET_OPTSPEED=y
CONFIG_MMCSD=y
CONFIG_MMCSD_SDIO=y
CONFIG_MQ_MAXMSGSIZE=64 CONFIG_MQ_MAXMSGSIZE=64
CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_BYTE_WRITE=y
CONFIG_MTD_PARTITION=y CONFIG_MTD_PARTITION=y
@@ -47,8 +47,6 @@ CONFIG_FS_SMARTFS=y
CONFIG_HAVE_CXX=y CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_INIT_ENTRYPOINT="spresense_main" CONFIG_INIT_ENTRYPOINT="spresense_main"
CONFIG_MMCSD=y
CONFIG_MMCSD_SDIO=y
CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_BYTE_WRITE=y
CONFIG_MTD_PARTITION=y CONFIG_MTD_PARTITION=y
CONFIG_MTD_SMART=y CONFIG_MTD_SMART=y
@@ -40,8 +40,6 @@ CONFIG_FS_SMARTFS=y
CONFIG_HAVE_CXX=y CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_INIT_ENTRYPOINT="spresense_main" CONFIG_INIT_ENTRYPOINT="spresense_main"
CONFIG_MMCSD=y
CONFIG_MMCSD_SDIO=y
CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_BYTE_WRITE=y
CONFIG_MTD_PARTITION=y CONFIG_MTD_PARTITION=y
CONFIG_MTD_SMART=y CONFIG_MTD_SMART=y
@@ -82,8 +82,6 @@ CONFIG_LIBC_EXECFUNCS=y
CONFIG_MEMCPY_VIK=y CONFIG_MEMCPY_VIK=y
CONFIG_MEMSET_64BIT=y CONFIG_MEMSET_64BIT=y
CONFIG_MEMSET_OPTSPEED=y CONFIG_MEMSET_OPTSPEED=y
CONFIG_MMCSD=y
CONFIG_MMCSD_SDIO=y
CONFIG_MQ_MAXMSGSIZE=64 CONFIG_MQ_MAXMSGSIZE=64
CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_BYTE_WRITE=y
CONFIG_MTD_PARTITION=y CONFIG_MTD_PARTITION=y
@@ -85,8 +85,6 @@ CONFIG_LIBC_EXECFUNCS=y
CONFIG_MEMCPY_VIK=y CONFIG_MEMCPY_VIK=y
CONFIG_MEMSET_64BIT=y CONFIG_MEMSET_64BIT=y
CONFIG_MEMSET_OPTSPEED=y CONFIG_MEMSET_OPTSPEED=y
CONFIG_MMCSD=y
CONFIG_MMCSD_SDIO=y
CONFIG_MQ_MAXMSGSIZE=64 CONFIG_MQ_MAXMSGSIZE=64
CONFIG_MTD_BYTE_WRITE=y CONFIG_MTD_BYTE_WRITE=y
CONFIG_MTD_PARTITION=y CONFIG_MTD_PARTITION=y
@@ -41,6 +41,7 @@
#include "cxd56_i2cdev.h" #include "cxd56_i2cdev.h"
#include "cxd56_spidev.h" #include "cxd56_spidev.h"
#include "cxd56_sdcard.h" #include "cxd56_sdcard.h"
#include "cxd56_automount.h"
#include "cxd56_wdt.h" #include "cxd56_wdt.h"
#include "cxd56_gpioif.h" #include "cxd56_gpioif.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 */
@@ -131,6 +131,20 @@ void board_sdcard_set_high_voltage(void);
void board_sdcard_set_low_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 * Name: board_sdcard_set_state_cb
* *
@@ -59,6 +59,10 @@ ifeq ($(CONFIG_CXD56_SDIO),y)
CSRCS += cxd56_sdcard.c CSRCS += cxd56_sdcard.c
endif endif
ifeq ($(CONFIG_CXD56_SDCARD_AUTOMOUNT),y)
CSRCS += cxd56_automount.c
endif
ifeq ($(CONFIG_CXD56_GAUGE),y) ifeq ($(CONFIG_CXD56_GAUGE),y)
CSRCS += cxd56_gauge.c CSRCS += cxd56_gauge.c
endif endif
@@ -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);
}
}
}
@@ -434,6 +434,12 @@ int cxd56_bringup(void)
} }
#endif #endif
#ifdef CONFIG_CXD56_SDCARD_AUTOMOUNT
/* Initialize the auto-mounter */
board_automount_initialize();
#endif
#ifdef CONFIG_CPUFREQ_RELEASE_LOCK #ifdef CONFIG_CPUFREQ_RELEASE_LOCK
/* Enable dynamic clock control and CPU clock down for power saving */ /* Enable dynamic clock control and CPU clock down for power saving */
+66 -64
View File
@@ -69,7 +69,9 @@ struct cxd56_sdhci_state_s
{ {
struct sdio_dev_s *sdhci; /* R/W device handle */ struct sdio_dev_s *sdhci; /* R/W device handle */
bool initialized; /* TRUE: SDHCI block driver is initialized */ bool initialized; /* TRUE: SDHCI block driver is initialized */
#ifdef CONFIG_MMCSD_HAVE_CARDDETECT
bool inserted; /* TRUE: card is inserted */ bool inserted; /* TRUE: card is inserted */
#endif
void (*cb)(bool); /* Callback function pointer to application */ 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"); finfo("Initializing SDHC slot 0\n");
g_sdhci.sdhci = cxd56_sdhci_initialize(0); 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"); _err("ERROR: Failed to initialize SDHC slot 0\n");
goto release_frequency_lock; goto release_frequency_lock;
@@ -135,7 +137,7 @@ static void board_sdcard_enable(void *arg)
if (ret != OK) if (ret != OK)
{ {
_err("ERROR: Failed to bind SDHC to the MMC/SD driver: %d\n", _err("ERROR: Failed to bind SDHC to the MMC/SD driver: %d\n",
ret); ret);
goto release_frequency_lock; goto release_frequency_lock;
} }
@@ -146,6 +148,7 @@ static void board_sdcard_enable(void *arg)
cxd56_sdhci_mediachange(g_sdhci.sdhci); cxd56_sdhci_mediachange(g_sdhci.sdhci);
#ifndef CONFIG_CXD56_SDCARD_AUTOMOUNT
if (nx_stat("/dev/mmcsd0", &stat_sdio, 1) == 0) if (nx_stat("/dev/mmcsd0", &stat_sdio, 1) == 0)
{ {
if (S_ISBLK(stat_sdio.st_mode)) 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 */ /* Callback to application to notice card is inserted */
if (g_sdhci.cb != NULL) if (g_sdhci.cb != NULL)
{ {
g_sdhci.cb(true); 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:
/* Release frequency lock */ /* Release frequency lock */
@@ -192,10 +202,11 @@ release_frequency_lock:
static void board_sdcard_disable(void *arg) static void board_sdcard_disable(void *arg)
{ {
int ret;
if (g_sdhci.initialized) if (g_sdhci.initialized)
{ {
#ifndef CONFIG_CXD56_SDCARD_AUTOMOUNT
int ret;
/* un-mount */ /* un-mount */
ret = nx_umount2("/mnt/sd0", 0); 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); 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 */ /* Report the new state to the SDIO driver */
cxd56_sdhci_mediachange(g_sdhci.sdhci); cxd56_sdhci_mediachange(g_sdhci.sdhci);
@@ -211,46 +230,22 @@ static void board_sdcard_disable(void *arg)
cxd56_sdhci_finalize(0); cxd56_sdhci_finalize(0);
g_sdhci.initialized = false; 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 #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 * Name: board_sdcard_detect_int
* *
* Description: * Description:
* Card detect interrupt handler * 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) 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); 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; return OK;
@@ -358,23 +344,20 @@ int board_sdcard_initialize(void)
/* Configure Interrupt pin with internal pull-up */ /* Configure Interrupt pin with internal pull-up */
cxd56_pin_config(PINCONF_SDIO_CD_GPIO); cxd56_pin_config(PINCONF_SDIO_CD_GPIO);
ret = cxd56_gpioint_config(PIN_SDIO_CD,
GPIOINT_PSEUDO_EDGE_FALL, /* Handle the case when SD card is already inserted */
board_sdcard_detect_int,
NULL); board_sdcard_detect_int(PIN_SDIO_CD, NULL, NULL);
if (ret < 0)
{ /* Configure Interrupt pin with internal pull-up */
_err("ERROR: Failed to configure GPIO int.\n");
} cxd56_gpioint_config(PIN_SDIO_CD, GPIOINT_PSEUDO_EDGE_BOTH,
board_sdcard_detect_int, NULL);
/* Enabling Interrupt */ /* Enabling Interrupt */
cxd56_gpioint_enable(PIN_SDIO_CD); cxd56_gpioint_enable(PIN_SDIO_CD);
#else #else
/* Initialize Card insert status */
g_sdhci.inserted = true;
/* Enable SDC */ /* Enable SDC */
board_sdcard_enable(NULL); board_sdcard_enable(NULL);
@@ -397,19 +380,16 @@ int board_sdcard_finalize(void)
/* At first, Disable interrupt of the card detection */ /* 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 #ifdef CONFIG_MMCSD_HAVE_CARDDETECT
/* Disabling Interrupt */ /* Disabling Interrupt */
cxd56_gpioint_disable(PIN_SDIO_CD); cxd56_gpioint_disable(PIN_SDIO_CD);
g_sdhci.inserted = false;
#endif #endif
board_sdcard_disable(NULL);
/* Disable SDIO pin configuration */ /* Disable SDIO pin configuration */
CXD56_PIN_CONFIGS(PINCONFS_SDIOA_GPIO); 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 * Name: board_sdcard_set_state_cb
* *