diff --git a/arch/arm/include/cxd56xx/hostif.h b/arch/arm/include/cxd56xx/hostif.h new file mode 100644 index 0000000000..3c58bd70a3 --- /dev/null +++ b/arch/arm/include/cxd56xx/hostif.h @@ -0,0 +1,136 @@ +/**************************************************************************** + * arch/arm/include/cxd56xx/hostif.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 __ARCH_ARM_INCLUDE_CXD56XX_HOSTIF_H +#define __ARCH_ARM_INCLUDE_CXD56XX_HOSTIF_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Host interface maximum number of buffers */ + +#define MAX_BUFFER_NUM 32 + +/* Host interface buffer attributes */ + +#define HOSTIF_BUFF_ATTR_ADDR_OFFSET(n) (((n) & 0x3) << 4) + /* 2 to the power of n */ +#define HOSTIF_BUFF_ATTR_FIXLEN (0 << 2) /* fixed length */ +#define HOSTIF_BUFF_ATTR_VARLEN (1 << 2) /* variable length */ +#define HOSTIF_BUFF_ATTR_WRITE (0 << 1) /* from target to host */ +#define HOSTIF_BUFF_ATTR_READ (1 << 1) /* from host to target */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* Common buffer configuration */ + +struct hostif_buff_s +{ + uint16_t size; + uint16_t flag; +}; + +/* I2C buffer configuration */ + +struct hostif_i2cconf_s +{ + int address; /* slave address */ + struct hostif_buff_s buff[MAX_BUFFER_NUM]; +}; + +/* SPI buffer configuration */ + +struct hostif_spiconf_s +{ + struct hostif_buff_s buff[MAX_BUFFER_NUM]; +}; + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: hostif_i2cinitialize + * + * Description: + * Initialize the host interface for I2C slave + * + * Input Parameter: + * config - pointer to I2C buffer configuration + * + * Returned Value: + * Return 0 on success. Otherwise, return a negated errno. + * + ****************************************************************************/ + +int hostif_i2cinitialize(FAR struct hostif_i2cconf_s *config); + +/**************************************************************************** + * Name: hostif_spiinitialize + * + * Description: + * Initialize the host interface for SPI slave + * + * Input Parameter: + * config - pointer to SPI buffer configuration + * + * Returned Value: + * Return 0 on success. Otherwise, return a negated errno. + * + ****************************************************************************/ + +int hostif_spiinitialize(FAR struct hostif_spiconf_s *config); + +/**************************************************************************** + * Name: hostif_uninitialize + * + * Description: + * Uninitialize the host interface + * + * Returned Value: + * Return 0 on success. Otherwise, return a negated errno. + * + ****************************************************************************/ + +int hostif_uninitialize(void); + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_INCLUDE_CXD56XX_HOSTIF_H */ diff --git a/arch/arm/src/cxd56xx/Kconfig b/arch/arm/src/cxd56xx/Kconfig index b3f525c963..0a1b8aed85 100644 --- a/arch/arm/src/cxd56xx/Kconfig +++ b/arch/arm/src/cxd56xx/Kconfig @@ -1093,6 +1093,45 @@ config CXD56_CISIF default n ---help--- CMOS image sensor interface for cx5602 chip + +config CXD56_HOSTIF + bool "Host interface" + default n + ---help--- + Host interface supports I2C or SPI slave feature. + +config CXD56_HOSTIF_DEBUG + bool "Host interface Debug Features" + default n + depends on CXD56_HOSTIF + ---help--- + Enable host interface device debug features. + +if CXD56_HOSTIF_DEBUG + +config CXD56_HOSTIF_DEBUG_ERROR + bool "Host interface Error Output" + default n + depends on DEBUG_ERROR + ---help--- + Enable host interface error output to SYSLOG. + +config CXD56_HOSTIF_DEBUG_WARN + bool "Host interface Warnings Output" + default n + depends on DEBUG_WARN + ---help--- + Enable host interface warning output to SYSLOG. + +config CXD56_HOSTIF_DEBUG_INFO + bool "Host interface Informational Output" + default n + depends on DEBUG_INFO + ---help--- + Enable host interface informational output to SYSLOG. + +endif # CXD56_HOSTIF_DEBUG + endmenu comment "Storage Options" diff --git a/arch/arm/src/cxd56xx/Make.defs b/arch/arm/src/cxd56xx/Make.defs index 1c386a0160..c61a72fcb9 100644 --- a/arch/arm/src/cxd56xx/Make.defs +++ b/arch/arm/src/cxd56xx/Make.defs @@ -201,3 +201,7 @@ endif ifeq ($(CONFIG_CXD56_BACKUPLOG),y) CHIP_CSRCS += cxd56_backuplog.c endif + +ifeq ($(CONFIG_CXD56_HOSTIF),y) +CHIP_CSRCS += cxd56_hostif.c +endif diff --git a/arch/arm/src/cxd56xx/cxd56_clock.c b/arch/arm/src/cxd56xx/cxd56_clock.c index a46acc354a..cc8cd548cb 100644 --- a/arch/arm/src/cxd56xx/cxd56_clock.c +++ b/arch/arm/src/cxd56xx/cxd56_clock.c @@ -2291,6 +2291,182 @@ uint32_t cxd56_get_img_vsync_baseclock(void) } } +static int cxd56_hostif_clock_ctrl(uint32_t block, uint32_t intr, int on) +{ + uint32_t val; + uint32_t stat; + int retry = 10000; + + putreg32(0xffffffff, CXD56_TOPREG_CRG_INT_CLR0); + + val = getreg32(CXD56_TOPREG_SYSIOP_CKEN); + if (on) + { + if ((val & block) == block) + { + /* Already clock on */ + + return OK; + } + + putreg32(val | block, CXD56_TOPREG_SYSIOP_CKEN); + } + else + { + if ((val & block) == 0) + { + /* Already clock off */ + + return OK; + } + + putreg32(val & ~block, CXD56_TOPREG_SYSIOP_CKEN); + } + + do + { + stat = getreg32(CXD56_TOPREG_CRG_INT_STAT_RAW0); + busy_wait(1000); + } + while (retry-- && !(stat & intr)); + + putreg32(0xffffffff, CXD56_TOPREG_CRG_INT_CLR0); + + return (retry) ? OK : -ETIMEDOUT; +} + +int cxd56_hostif_clock_enable(void) +{ + int ret = OK; + uint32_t mask; + uint32_t intr; + + /* Enable HOSTIF IRAM/DRAM & general RAM memory power. */ + + putreg32((0x3 << 24) | 0xf, CXD56_TOPREG_HOSTIFC_RAMMODE_SEL); + + do_power_control(); + + mask = CKEN_HOSSPI | CKEN_HOSI2C | CKEN_HOSTIFC_SEQ | CKEN_BRG_HOST | + CKEN_I2CS | CKEN_PCLK_HOSTIFC | CKEN_PCLK_UART0 | CKEN_UART0; + + if (getreg32(CXD56_TOPREG_SYSIOP_CKEN) & mask) + { + /* Already enabled */ + + return ret; + } + + putreg32(0, CXD56_TOPREG_CKDIV_HOSTIFC); + putreg32(0, CXD56_TOPREG_CKSEL_SYSIOP); + + mask = CKEN_HOSSPI | CKEN_HOSI2C | CKEN_BRG_HOST | + CKEN_I2CS | CKEN_PCLK_HOSTIFC; + + intr = CRG_CK_BRG_HOST | CRG_CK_I2CS | CRG_CK_PCLK_HOSTIFC; + + ret = cxd56_hostif_clock_ctrl(mask, intr, 1); + if (ret < 0) + { + return ret; + } + + ret = cxd56_hostif_clock_ctrl(mask, intr, 0); + if (ret < 0) + { + return ret; + } + + modifyreg32(CXD56_TOPREG_SWRESET_BUS, 0, XRST_HOSTIFC); + ret = cxd56_hostif_clock_ctrl(mask, intr, 1); + + return ret; +} + +int cxd56_hostif_clock_disable(void) +{ + int ret = OK; + uint32_t mask; + uint32_t intr; + + mask = CKEN_HOSSPI | CKEN_HOSI2C | CKEN_HOSTIFC_SEQ | CKEN_BRG_HOST | + CKEN_I2CS | CKEN_PCLK_HOSTIFC | CKEN_PCLK_UART0 | CKEN_UART0; + + if (0 == (getreg32(CXD56_TOPREG_SYSIOP_CKEN) & mask)) + { + /* Already disabled */ + + return ret; + } + + mask = CKEN_HOSSPI | CKEN_HOSI2C | CKEN_BRG_HOST | + CKEN_I2CS | CKEN_PCLK_HOSTIFC; + + intr = CRG_CK_BRG_HOST | CRG_CK_I2CS | CRG_CK_PCLK_HOSTIFC; + + ret = cxd56_hostif_clock_ctrl(mask, intr, 0); + if (ret < 0) + { + return ret; + } + + modifyreg32(CXD56_TOPREG_SWRESET_BUS, XRST_HOSTIFC, 0); + + /* Disable HOSTIF IRAM/DRAM & general RAM memory power. */ + + putreg32(0x3, CXD56_TOPREG_HOSTIFC_RAMMODE_SEL); + + do_power_control(); + + return ret; +} + +int cxd56_hostseq_clock_enable(void) +{ + int ret = OK; + + if (getreg32(CXD56_TOPREG_SYSIOP_CKEN) & CKEN_HOSTIFC_SEQ) + { + /* Already enabled */ + + return ret; + } + + ret = cxd56_hostif_clock_ctrl(CKEN_HOSTIFC_SEQ, CRG_CK_HOSTIFC_SEQ, 1); + if (ret < 0) + { + return ret; + } + + ret = cxd56_hostif_clock_ctrl(CKEN_HOSTIFC_SEQ, CRG_CK_HOSTIFC_SEQ, 0); + if (ret < 0) + { + return ret; + } + + modifyreg32(CXD56_TOPREG_SWRESET_BUS, 0, XRST_HOSTIFC_ISOP); + ret = cxd56_hostif_clock_ctrl(CKEN_HOSTIFC_SEQ, CRG_CK_HOSTIFC_SEQ, 1); + + return ret; +} + +int cxd56_hostseq_clock_disable(void) +{ + int ret = OK; + + if (0 == (getreg32(CXD56_TOPREG_SYSIOP_CKEN) & CKEN_HOSTIFC_SEQ)) + { + /* Already disabled */ + + return ret; + } + + modifyreg32(CXD56_TOPREG_SWRESET_BUS, XRST_HOSTIFC_ISOP, 0); + ret = cxd56_hostif_clock_ctrl(CKEN_HOSTIFC_SEQ, CRG_CK_HOSTIFC_SEQ, 0); + + return ret; +} + int up_pmramctrl(int cmd, uintptr_t addr, size_t size) { int startidx; diff --git a/arch/arm/src/cxd56xx/cxd56_clock.h b/arch/arm/src/cxd56xx/cxd56_clock.h index 1f488ed648..81014ca1fb 100644 --- a/arch/arm/src/cxd56xx/cxd56_clock.h +++ b/arch/arm/src/cxd56xx/cxd56_clock.h @@ -684,6 +684,46 @@ uint32_t cxd56_get_img_vsync_baseclock(void); uint32_t cxd56_get_appsmp_baseclock(void); +/**************************************************************************** + * Name: cxd56_hostif_clock_enable + * + * Description: + * Enable clock of the hostif block + * + ****************************************************************************/ + +int cxd56_hostif_clock_enable(void); + +/**************************************************************************** + * Name: cxd56_hostif_clock_disable + * + * Description: + * Disable clock of the hostif block + * + ****************************************************************************/ + +int cxd56_hostif_clock_disable(void); + +/**************************************************************************** + * Name: cxd56_hostseq_clock_enable + * + * Description: + * Enable clock of the hostif sequencer block + * + ****************************************************************************/ + +int cxd56_hostseq_clock_enable(void); + +/**************************************************************************** + * Name: cxd56_hostseq_clock_disable + * + * Description: + * Disable clock of the hostif sequencer block + * + ****************************************************************************/ + +int cxd56_hostseq_clock_disable(void); + #undef EXTERN #if defined(__cplusplus) } diff --git a/arch/arm/src/cxd56xx/cxd56_hostif.c b/arch/arm/src/cxd56xx/cxd56_hostif.c new file mode 100644 index 0000000000..c0d3934400 --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_hostif.c @@ -0,0 +1,594 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_hostif.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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "chip.h" +#include "up_arch.h" + +#include "cxd56_clock.h" +#include "cxd56_pinconfig.h" +#include "cxd56_icc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Debug */ + +#ifdef CONFIG_CXD56_HOSTIF_DEBUG_ERROR +#define hiferr(format, ...) _err(format, ##__VA_ARGS__) +#else +#define hiferr(x, ...) +#endif +#ifdef CONFIG_CXD56_HOSTIF_DEBUG_WARN +#define hifwarn(format, ...) _warn(format, ##__VA_ARGS__) +#else +#define hifwarn(x, ...) +#endif +#ifdef CONFIG_CXD56_HOSTIF_DEBUG_INFO +#define hifinfo(format, ...) _info(format, ##__VA_ARGS__) +#else +#define hifinfo(x, ...) +#endif + +/* Message id definitions */ + +#define HIF_I2C_INIT 1 +#define HIF_SPI_INIT 2 +#define HIF_READ_DEVICE 3 +#define HIF_WRITE_DEVICE 4 + +/* Message timeout definition in units of msec */ + +#define HIF_TIMEOUT 5000 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Host interface device structure for each buffer */ + +struct cxd56_hifdev_s +{ + int id; + uint32_t flags; + const void *buffer; + size_t len; + sem_t exclsem; + int crefs; +}; + +/* Host interface driver structure */ + +struct cxd56_hifdrv_s +{ + struct cxd56_hifdev_s *dev; + int ndev; + sem_t sync; + int errcode; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Character driver methods */ + +static int hif_open(FAR struct file *filep); +static int hif_close(FAR struct file *filep); +static off_t hif_seek(FAR struct file *filep, off_t offset, + int whence); +static ssize_t hif_read(FAR struct file *filep, FAR char *buffer, + size_t len); +static ssize_t hif_write(FAR struct file *filep, + FAR const char *buffer, size_t len); +static int hif_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); +static int hif_poll(FAR struct file *filep, FAR struct pollfd *fds, + bool setup); +static int hif_unlink(FAR struct inode *inode); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Host interface driver */ + +static struct cxd56_hifdrv_s g_hifdrv; + +/* Host interface operations */ + +static const struct file_operations g_hif_fops = +{ + hif_open, /* open */ + hif_close, /* close */ + hif_read, /* read */ + hif_write, /* write */ + hif_seek, /* seek */ + hif_ioctl, /* ioctl */ + hif_poll, /* poll */ + hif_unlink /* unlink */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int hif_sendmsg(uint8_t id, void *arg) +{ + struct cxd56_hifdrv_s *drv = &g_hifdrv; + iccmsg_t msg; + int ret; + + /* Check parameters */ + + DEBUGASSERT((HIF_I2C_INIT <= id) && (id <= HIF_WRITE_DEVICE)); + DEBUGASSERT(arg); + + /* Send any message to system CPU */ + + msg.cpuid = 0; + msg.msgid = id; + msg.protodata = id; + msg.data = (uint32_t)arg; + + ret = cxd56_iccsend(CXD56_PROTO_HOSTIF, &msg, HIF_TIMEOUT); + if (ret < 0) + { + hiferr("ERROR: Send message (%d)\n", ret); + return ret; + } + + /* Wait for reply message from system CPU */ + + nxsem_wait_uninterruptible(&drv->sync); + + /* Get the error code returned from system cpu */ + + ret = drv->errcode; + + return ret; +} + +static int hif_open(FAR struct file *filep) +{ + FAR struct inode *inode; + FAR struct cxd56_hifdev_s *priv; + + DEBUGASSERT(filep && filep->f_inode); + inode = filep->f_inode; + + priv = (FAR struct cxd56_hifdev_s *)inode->i_private; + DEBUGASSERT(priv); + + /* Check parameters */ + + if ((filep->f_oflags & O_WRONLY) != 0 && + (filep->f_oflags & O_RDONLY) != 0) + { + return -EACCES; + } + + if ((filep->f_oflags & O_RDONLY) && + ((priv->flags & HOSTIF_BUFF_ATTR_READ) == 0)) + { + return -EINVAL; + } + + if ((filep->f_oflags & O_WRONLY) && + ((priv->flags & HOSTIF_BUFF_ATTR_WRITE) != 0)) + { + return -EINVAL; + } + + /* Increment reference counter */ + + nxsem_wait_uninterruptible(&priv->exclsem); + + priv->crefs++; + DEBUGASSERT(priv->crefs > 0); + + if (priv->crefs > 1) + { + nxsem_post(&priv->exclsem); + return OK; + } + + /* Check if non-blocking mode */ + + if (filep->f_oflags & O_NONBLOCK) + { + priv->flags |= O_NONBLOCK; + } + + nxsem_post(&priv->exclsem); + + return OK; +} + +static int hif_close(FAR struct file *filep) +{ + FAR struct inode *inode; + FAR struct cxd56_hifdev_s *priv; + + DEBUGASSERT(filep && filep->f_inode); + inode = filep->f_inode; + + priv = (FAR struct cxd56_hifdev_s *)inode->i_private; + DEBUGASSERT(priv); + + /* Decrement reference counter */ + + nxsem_wait_uninterruptible(&priv->exclsem); + + DEBUGASSERT(priv->crefs > 0); + priv->crefs--; + + nxsem_post(&priv->exclsem); + + return OK; +} + +static off_t hif_seek(FAR struct file *filep, off_t offset, int whence) +{ + return OK; +} + +static ssize_t hif_read(FAR struct file *filep, FAR char *buffer, size_t len) +{ + FAR struct inode *inode; + FAR struct cxd56_hifdev_s *priv; + int ret; + + DEBUGASSERT(filep && filep->f_inode); + inode = filep->f_inode; + + priv = (FAR struct cxd56_hifdev_s *)inode->i_private; + DEBUGASSERT(priv); + + /* Check parameters */ + + DEBUGASSERT(buffer); + + if ((filep->f_oflags & O_RDONLY) == 0) + { + return -EACCES; + } + + /* Receive data from host */ + + priv->buffer = buffer; + priv->len = len; + + ret = hif_sendmsg(HIF_READ_DEVICE, priv); + + return ret; +} + +static ssize_t hif_write(FAR struct file *filep, + FAR const char *buffer, size_t len) +{ + FAR struct inode *inode; + FAR struct cxd56_hifdev_s *priv; + int ret; + + DEBUGASSERT(filep && filep->f_inode); + inode = filep->f_inode; + + priv = (FAR struct cxd56_hifdev_s *)inode->i_private; + DEBUGASSERT(priv); + + /* Check parameters */ + + DEBUGASSERT(buffer); + + if ((filep->f_oflags & O_WRONLY) == 0) + { + return -EACCES; + } + + /* Send data to host */ + + priv->buffer = buffer; + priv->len = len; + + ret = hif_sendmsg(HIF_WRITE_DEVICE, priv); + + return ret; +} + +static int hif_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + return OK; +} + +static int hif_poll(FAR struct file *filep, + FAR struct pollfd *fds, bool setup) +{ + return OK; +} + +static int hif_unlink(FAR struct inode *inode) +{ + return OK; +} + +static int hif_rxhandler(int cpuid, int protoid, + uint32_t pdata, uint32_t data, + FAR void *userdata) +{ + struct cxd56_hifdrv_s *drv = &g_hifdrv; + + DEBUGASSERT(cpuid == 0); + DEBUGASSERT(protoid == CXD56_PROTO_HOSTIF); + + drv->errcode = (int)data; + + nxsem_post(&drv->sync); + + return OK; +} + +static int hif_initialize(struct hostif_buff_s *buffer) +{ + struct cxd56_hifdrv_s *drv = &g_hifdrv; + struct cxd56_hifdev_s *priv; + char devpath[16]; + int num; + int ret; + + /* Check parameters */ + + DEBUGASSERT(buffer); + + memset(drv, 0, sizeof(struct cxd56_hifdrv_s)); + + /* Get the number of devices */ + + for (num = 0; num < MAX_BUFFER_NUM; num++) + { + if (buffer[num].size == 0) + { + break; + } + } + + /* Setup driver structure */ + + drv->dev = + (struct cxd56_hifdev_s *)kmm_malloc(sizeof(struct cxd56_hifdev_s) * num); + if (drv->dev == NULL) + { + hiferr("ERROR: hostif allocation failed\n"); + + return -ENOMEM; + } + + drv->ndev = num; + + /* Setup each device structure */ + + for (num = 0; num < drv->ndev; num++) + { + priv = &drv->dev[num]; + + priv->id = num; + priv->flags = buffer[num].flag; + snprintf(devpath, sizeof(devpath), "/dev/hostif%c%d", + (priv->flags & HOSTIF_BUFF_ATTR_READ) ? 'r' : 'w', num); + + ret = register_driver(devpath, &g_hif_fops, 0666, priv); + if (ret < 0) + { + hiferr("ERROR: Failed to register %s (%d)\n", devpath, ret); + kmm_free(drv->dev); + return ret; + } + + nxsem_init(&priv->exclsem, 0, 1); + priv->crefs = 0; + } + + /* Enable hostif clock */ + + ret = cxd56_hostif_clock_enable(); + if (ret < 0) + { + hiferr("ERROR: Enable clock (%d)\n", ret); + kmm_free(drv->dev); + return ret; + } + + /* Initialize communication with system CPU */ + + cxd56_iccinit(CXD56_PROTO_HOSTIF); + + nxsem_init(&drv->sync, 0, 0); + nxsem_setprotocol(&drv->sync, SEM_PRIO_NONE); + + ret = cxd56_iccregisterhandler(CXD56_PROTO_HOSTIF, hif_rxhandler, NULL); + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: hostif_i2cinitialize + * + * Description: + * Initialize the host interface for I2C slave + * + * Input Parameter: + * config - pointer to I2C buffer configuration + * + * Returned Value: + * Return 0 on success. Otherwise, return a negated errno. + * + ****************************************************************************/ + +int hostif_i2cinitialize(struct hostif_i2cconf_s *config) +{ + int ret; + + DEBUGASSERT(config); + + /* Initialize common driver */ + + ret = hif_initialize(config->buff); + if (ret < 0) + { + hiferr("ERROR: Failed to initialize (%d)\n", ret); + return ret; + } + + /* Initialize I2C driver */ + + ret = hif_sendmsg(HIF_I2C_INIT, config); + if (ret < 0) + { + hiferr("ERROR: Initialize I2C (%d)\n", ret); + return ret; + } + + /* Enable hostif sequencer clock */ + + ret = cxd56_hostseq_clock_enable(); + if (ret < 0) + { + hiferr("ERROR: Enable sequencer clock (%d)\n", ret); + return ret; + } + + /* Pin setting */ + + CXD56_PIN_CONFIGS(PINCONFS_SPI2A_I2C3); + + return OK; +} + +/**************************************************************************** + * Name: hostif_spiinitialize + * + * Description: + * Initialize the host interface for SPI slave + * + * Input Parameter: + * config - pointer to SPI buffer configuration + * + * Returned Value: + * Return 0 on success. Otherwise, return a negated errno. + * + ****************************************************************************/ + +int hostif_spiinitialize(struct hostif_spiconf_s *config) +{ + int ret; + + DEBUGASSERT(config); + + /* Initialize common driver */ + + ret = hif_initialize(config->buff); + if (ret < 0) + { + hiferr("ERROR: Failed to initialize (%d)\n", ret); + return ret; + } + + /* Initialize SPI driver */ + + ret = hif_sendmsg(HIF_SPI_INIT, config); + if (ret < 0) + { + hiferr("ERROR: Initialize SPI (%d)\n", ret); + return ret; + } + + /* Enable hostif sequencer clock */ + + ret = cxd56_hostseq_clock_enable(); + if (ret < 0) + { + hiferr("ERROR: Enable sequencer clock (%d)\n", ret); + return ret; + } + + /* Pin setting */ + + CXD56_PIN_CONFIGS(PINCONFS_SPI2); + + return OK; +} + +/**************************************************************************** + * Name: hostif_uninitialize + * + * Description: + * Uninitialize the host interface + * + * Returned Value: + * Return 0 on success. Otherwise, return a negated errno. + * + ****************************************************************************/ + +int hostif_uninitialize(void) +{ + struct cxd56_hifdrv_s *drv = &g_hifdrv; + struct cxd56_hifdev_s *priv; + char devpath[16]; + int num; + + for (num = 0; num < drv->ndev; num++) + { + priv = &drv->dev[num]; + + snprintf(devpath, sizeof(devpath), "/dev/hostif%c%d", + (priv->flags & HOSTIF_BUFF_ATTR_READ) ? 'r' : 'w', num); + unregister_driver(devpath); + } + + if (drv->dev) + { + kmm_free(drv->dev); + } + + return OK; +} diff --git a/arch/arm/src/cxd56xx/cxd56_icc.h b/arch/arm/src/cxd56xx/cxd56_icc.h index a27774968b..59d9ed0737 100644 --- a/arch/arm/src/cxd56xx/cxd56_icc.h +++ b/arch/arm/src/cxd56xx/cxd56_icc.h @@ -32,6 +32,7 @@ #define CXD56_PROTO_HOTSLEEP 8 #define CXD56_PROTO_IMAGE 9 #define CXD56_PROTO_PM 10 /* Power manager */ +#define CXD56_PROTO_HOSTIF 11 #define CXD56_PROTO_SYSCTL 12 #define CXD56_PROTO_GNSS 13 #define CXD56_PROTO_SIG 15 /* Inter-CPU Comm signal */