099980efb5
Signed-off-by: Barry Xu <barry.xu@sony.com>
285 lines
8.0 KiB
C
285 lines
8.0 KiB
C
/****************************************************************************
|
|
* boards/arm/cxd56xx/common/src/cxd56_gs2200m.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 <debug.h>
|
|
#include <inttypes.h>
|
|
|
|
#include <nuttx/arch.h>
|
|
#include <nuttx/config.h>
|
|
#include <nuttx/board.h>
|
|
#include <nuttx/spi/spi.h>
|
|
#include <nuttx/irq.h>
|
|
#include <nuttx/wireless/gs2200m.h>
|
|
|
|
#include <arch/chip/pin.h>
|
|
|
|
#include "cxd56_pinconfig.h"
|
|
#include "cxd56_spi.h"
|
|
#include "cxd56_dmac.h"
|
|
#include "cxd56_gpio.h"
|
|
#include "cxd56_gpioint.h"
|
|
|
|
#define DMA_TXCH (CONFIG_CXD56_DMAC_SPI5_TX_CH)
|
|
#define DMA_RXCH (CONFIG_CXD56_DMAC_SPI5_RX_CH)
|
|
#define DMA_TXCH_CFG (CXD56_DMA_PERIPHERAL_SPI5_TX)
|
|
#define DMA_RXCH_CFG (CXD56_DMA_PERIPHERAL_SPI5_RX)
|
|
#define SPI_TX_MAXSIZE (CONFIG_CXD56_DMAC_SPI5_TX_MAXSIZE)
|
|
#define SPI_RX_MAXSIZE (CONFIG_CXD56_DMAC_SPI5_RX_MAXSIZE)
|
|
|
|
#if defined(CONFIG_WIFI_BOARD_IS110B_HARDWARE_VERSION_10B)
|
|
/* v1.0b */
|
|
#define GS2200M_GPIO_37 (PIN_UART2_CTS)
|
|
#define GS2200M_EXT_RTC_RESET_IN (PIN_EMMC_DATA3)
|
|
#elif defined(CONFIG_WIFI_BOARD_IS110B_HARDWARE_VERSION_10C)
|
|
/* v1.0c */
|
|
#define GS2200M_GPIO_37 (PIN_EMMC_DATA2)
|
|
#define GS2200M_EXT_RTC_RESET_IN (PIN_EMMC_DATA3)
|
|
#else
|
|
/* v1.0a */
|
|
#define GS2200M_GPIO_37 (PIN_UART2_CTS)
|
|
#define GS2200M_EXT_RTC_RESET_IN (PIN_UART2_RTS)
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Private Function Prototypes
|
|
****************************************************************************/
|
|
|
|
static int gs2200m_irq_attach(xcpt_t, FAR void *);
|
|
static void gs2200m_irq_enable(void);
|
|
static void gs2200m_irq_disable(void);
|
|
static uint32_t gs2200m_dready(int *);
|
|
static void gs2200m_reset(bool);
|
|
|
|
/****************************************************************************
|
|
* Private Data
|
|
****************************************************************************/
|
|
|
|
static const struct gs2200m_lower_s g_wifi_lower =
|
|
{
|
|
.attach = gs2200m_irq_attach,
|
|
.enable = gs2200m_irq_enable,
|
|
.disable = gs2200m_irq_disable,
|
|
.dready = gs2200m_dready,
|
|
.reset = gs2200m_reset
|
|
};
|
|
|
|
static FAR void *g_devhandle = NULL;
|
|
static volatile int32_t _enable_count = 0;
|
|
static volatile uint32_t _n_called;
|
|
|
|
/****************************************************************************
|
|
* Private Functions
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: gs2200m_irq_attach
|
|
****************************************************************************/
|
|
|
|
static int gs2200m_irq_attach(xcpt_t handler, FAR void *arg)
|
|
{
|
|
cxd56_gpioint_config(GS2200M_GPIO_37,
|
|
GPIOINT_LEVEL_HIGH,
|
|
handler,
|
|
arg);
|
|
return 0;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: gs2200m_irq_enable
|
|
****************************************************************************/
|
|
|
|
static void gs2200m_irq_enable(void)
|
|
{
|
|
irqstate_t flags = enter_critical_section();
|
|
|
|
wlinfo("== ec:%" PRId32 " called=%" PRId32 " \n",
|
|
_enable_count, _n_called++);
|
|
|
|
if (0 == _enable_count)
|
|
{
|
|
cxd56_gpioint_enable(GS2200M_GPIO_37);
|
|
}
|
|
|
|
_enable_count++;
|
|
|
|
leave_critical_section(flags);
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: gs2200m_irq_disable
|
|
****************************************************************************/
|
|
|
|
static void gs2200m_irq_disable(void)
|
|
{
|
|
irqstate_t flags = enter_critical_section();
|
|
|
|
wlinfo("== ec:%" PRId32 " called=%" PRId32 " \n",
|
|
_enable_count, _n_called++);
|
|
|
|
_enable_count--;
|
|
|
|
if (0 == _enable_count)
|
|
{
|
|
cxd56_gpioint_disable(GS2200M_GPIO_37);
|
|
}
|
|
|
|
leave_critical_section(flags);
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: gs2200m_dready
|
|
****************************************************************************/
|
|
|
|
static uint32_t gs2200m_dready(int *ec)
|
|
{
|
|
irqstate_t flags = enter_critical_section();
|
|
|
|
uint32_t r = cxd56_gpio_read(GS2200M_GPIO_37);
|
|
|
|
if (ec)
|
|
{
|
|
/* Copy enable count (just for debug) */
|
|
|
|
*ec = _enable_count;
|
|
}
|
|
|
|
leave_critical_section(flags);
|
|
return r;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: gs2200m_reset
|
|
****************************************************************************/
|
|
|
|
static void gs2200m_reset(bool reset)
|
|
{
|
|
cxd56_gpio_write(GS2200M_EXT_RTC_RESET_IN, !reset);
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: spi_pincontrol
|
|
*
|
|
* Description:
|
|
* Configure the SPI pin
|
|
*
|
|
* Input Parameter:
|
|
* on - true: enable pin, false: disable pin
|
|
****************************************************************************/
|
|
|
|
static void spi_pincontrol(int bus, bool on)
|
|
{
|
|
if (bus == 5)
|
|
{
|
|
#ifdef CONFIG_CXD56_SPI5_PINMAP_EMMC
|
|
if (on)
|
|
{
|
|
CXD56_PIN_CONFIGS(PINCONFS_EMMCA_SPI5);
|
|
}
|
|
else
|
|
{
|
|
CXD56_PIN_CONFIGS(PINCONFS_EMMCA_GPIO);
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONFIG_CXD56_SPI5_PINMAP_SDIO
|
|
if (on)
|
|
{
|
|
CXD56_PIN_CONFIGS(PINCONFS_SDIOA_SPI5);
|
|
}
|
|
else
|
|
{
|
|
CXD56_PIN_CONFIGS(PINCONFS_SDIOA_GPIO);
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Public Functions
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: board_gs2200m_initialize
|
|
****************************************************************************/
|
|
|
|
int board_gs2200m_initialize(FAR const char *devpath, int bus)
|
|
{
|
|
FAR struct spi_dev_s *spi;
|
|
DMA_HANDLE hdl;
|
|
dma_config_t conf;
|
|
|
|
wlinfo("Initializing GS2200M..\n");
|
|
|
|
if (!g_devhandle)
|
|
{
|
|
/* Change UART2 to GPIO */
|
|
|
|
CXD56_PIN_CONFIGS(PINCONFS_UART2_GPIO);
|
|
cxd56_gpio_config(GS2200M_GPIO_37, true);
|
|
cxd56_gpio_config(GS2200M_EXT_RTC_RESET_IN, false);
|
|
|
|
/* Initialize spi device */
|
|
|
|
spi = cxd56_spibus_initialize(bus);
|
|
|
|
if (!spi)
|
|
{
|
|
wlerr("ERROR: Failed to initialize spi%d.\n", bus);
|
|
return -ENODEV;
|
|
}
|
|
|
|
hdl = cxd56_dmachannel(DMA_TXCH, SPI_TX_MAXSIZE);
|
|
if (hdl)
|
|
{
|
|
conf.channel_cfg = DMA_TXCH_CFG;
|
|
conf.dest_width = CXD56_DMAC_WIDTH8;
|
|
conf.src_width = CXD56_DMAC_WIDTH8;
|
|
cxd56_spi_dmaconfig(bus, CXD56_SPI_DMAC_CHTYPE_TX, hdl, &conf);
|
|
}
|
|
|
|
hdl = cxd56_dmachannel(DMA_RXCH, SPI_RX_MAXSIZE);
|
|
if (hdl)
|
|
{
|
|
conf.channel_cfg = DMA_RXCH_CFG;
|
|
conf.dest_width = CXD56_DMAC_WIDTH8;
|
|
conf.src_width = CXD56_DMAC_WIDTH8;
|
|
cxd56_spi_dmaconfig(bus, CXD56_SPI_DMAC_CHTYPE_RX, hdl, &conf);
|
|
}
|
|
|
|
/* Enable SPI5 */
|
|
|
|
spi_pincontrol(bus, true);
|
|
|
|
g_devhandle = gs2200m_register(devpath, spi, &g_wifi_lower);
|
|
|
|
if (!g_devhandle)
|
|
{
|
|
wlerr("ERROR: Failed to register gs2200m driver.\n");
|
|
return -ENODEV;
|
|
}
|
|
}
|
|
|
|
return OK;
|
|
}
|