boards/cxd56xx/spresense: add fs automount driver for SD Card
Signed-off-by: Petro Karashchenko <petro.karashchenko@gmail.com>
This commit is contained in:
parent
78248183aa
commit
5f92c62874
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
61
boards/arm/cxd56xx/spresense/configs/nsh_automount/defconfig
Normal file
61
boards/arm/cxd56xx/spresense/configs/nsh_automount/defconfig
Normal 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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
||||
|
119
boards/arm/cxd56xx/spresense/include/cxd56_automount.h
Normal file
119
boards/arm/cxd56xx/spresense/include/cxd56_automount.h
Normal 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 */
|
@ -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
|
||||
*
|
||||
|
@ -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
|
||||
|
322
boards/arm/cxd56xx/spresense/src/cxd56_automount.c
Normal file
322
boards/arm/cxd56xx/spresense/src/cxd56_automount.c
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user