drivers/i3c: support i3c driver model
Reference to: https://github.com/torvalds/linux/tree/master/drivers/i3c Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This commit is contained in:
parent
a01d9e9ce0
commit
5b48dea4f5
17 changed files with 5399 additions and 0 deletions
31
Kconfig
31
Kconfig
|
|
@ -1603,6 +1603,37 @@ config DEBUG_I2S_INFO
|
|||
|
||||
endif # DEBUG_I2S
|
||||
|
||||
config DEBUG_I3C
|
||||
bool "I3C Debug Features"
|
||||
default n
|
||||
depends on I3C
|
||||
---help---
|
||||
Enable I3C debug features.
|
||||
|
||||
Support for this debug option is architecture-specific and may not
|
||||
be available for some MCUs.
|
||||
|
||||
if DEBUG_I3C
|
||||
|
||||
config DEBUG_I3C_ERROR
|
||||
bool "I3C Error Output"
|
||||
default n
|
||||
depends on DEBUG_ERROR
|
||||
---help---
|
||||
Enable I3C driver error output to SYSLOG.
|
||||
|
||||
Support for this debug option is architecture-specific and may not
|
||||
be available for some MCUs.
|
||||
|
||||
config DEBUG_I3C_INFO
|
||||
bool "I3C Informational Output"
|
||||
default n
|
||||
depends on DEBUG_INFO
|
||||
---help---
|
||||
Enable I3C driver informational output to SYSLOG.
|
||||
|
||||
endif # DEBUG_I3C
|
||||
|
||||
config DEBUG_PWM
|
||||
bool "PWM Debug Features"
|
||||
default n
|
||||
|
|
|
|||
11
LICENSE
11
LICENSE
|
|
@ -8674,3 +8674,14 @@ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
drivers/i3c/device.c
|
||||
drivers/i3c/i3c_driver.c
|
||||
drivers/i3c/master.c
|
||||
drivers/i3c/internals.h
|
||||
======================
|
||||
|
||||
Copyright (C) 2018 Cadence Design Systems Inc.
|
||||
Author: Boris Brezillon <boris.brezillon@bootlin.com>
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ source "drivers/loop/Kconfig"
|
|||
source "drivers/can/Kconfig"
|
||||
source "drivers/clk/Kconfig"
|
||||
source "drivers/i2c/Kconfig"
|
||||
source "drivers/i3c/Kconfig"
|
||||
source "drivers/spi/Kconfig"
|
||||
source "drivers/i2s/Kconfig"
|
||||
source "drivers/ipcc/Kconfig"
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ include math/Make.defs
|
|||
include motor/Make.defs
|
||||
include i2c/Make.defs
|
||||
include i2s/Make.defs
|
||||
include i3c/Make.defs
|
||||
include ipcc/Make.defs
|
||||
include input/Make.defs
|
||||
include ioexpander/Make.defs
|
||||
|
|
|
|||
29
drivers/i3c/CMakeLists.txt
Normal file
29
drivers/i3c/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# ##############################################################################
|
||||
# drivers/i3c/CMakeLists.txt
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# ##############################################################################
|
||||
|
||||
if(CONFIG_I3C)
|
||||
set(SRCS master.c device.c)
|
||||
|
||||
if(CONFIG_I3C_DRIVER)
|
||||
list(APPEND SRCS i3c_driver.c)
|
||||
endif()
|
||||
|
||||
target_sources(drivers PRIVATE ${SRCS})
|
||||
endif()
|
||||
24
drivers/i3c/Kconfig
Normal file
24
drivers/i3c/Kconfig
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see the file kconfig-language.txt in the NuttX tools repository.
|
||||
#
|
||||
|
||||
menuconfig I3C
|
||||
bool "I3C Driver Support"
|
||||
default n
|
||||
---help---
|
||||
This selection enables building of the "upper-half" I3C driver.
|
||||
See include/nuttx/i3c/master.h for further I3C driver information.
|
||||
|
||||
if I3C
|
||||
|
||||
config I3C_DRIVER
|
||||
bool "I3C character driver"
|
||||
default n
|
||||
---help---
|
||||
Build in support for a character driver at /dev/i3c[N] that may be
|
||||
used to perform I3C bus transfers from applications. The intent of
|
||||
this driver is to support I3C testing. It is not suitable for use
|
||||
in any real driver application.
|
||||
|
||||
endif # I3C
|
||||
35
drivers/i3c/Make.defs
Normal file
35
drivers/i3c/Make.defs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
############################################################################
|
||||
# drivers/i3c/Make.defs
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
# Include I3C driver build surrport
|
||||
|
||||
ifeq ($(CONFIG_I3C),y)
|
||||
|
||||
CSRCS += master.c device.c
|
||||
|
||||
ifeq ($(CONFIG_I3C_DRIVER),y)
|
||||
CSRCS += i3c_driver.c
|
||||
endif
|
||||
|
||||
DEPPATH += --dep-path i3c
|
||||
VPATH += :i3c
|
||||
CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)drivers$(DELIM)i3c
|
||||
|
||||
endif # CONFIG_I3C
|
||||
310
drivers/i3c/device.c
Normal file
310
drivers/i3c/device.c
Normal file
|
|
@ -0,0 +1,310 @@
|
|||
/****************************************************************************
|
||||
* drivers/i3c/device.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 "internals.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: i3c_device_do_priv_xfers
|
||||
*
|
||||
* Description:
|
||||
* Do I3C SDR private transfers directed to a specific device.
|
||||
*
|
||||
* Initiate one or several private SDR transfers with @dev.
|
||||
*
|
||||
* This function can sleep and thus cannot be called in atomic context.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - Device with which the transfers should be done
|
||||
* xfers - Array of transfers
|
||||
* nxfers - Number of transfers
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 in case of success, a negative error core otherwise.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int i3c_device_do_priv_xfers(FAR const struct i3c_device *dev,
|
||||
FAR struct i3c_priv_xfer *xfers,
|
||||
int nxfers)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
if (nxfers < 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < nxfers; i++)
|
||||
{
|
||||
if (!xfers[i].len || !xfers[i].data.in)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
i3c_bus_normaluse_lock(dev->bus);
|
||||
ret = i3c_dev_do_priv_xfers_locked(dev->desc, xfers, nxfers);
|
||||
i3c_bus_normaluse_unlock(dev->bus);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: i3c_device_get_info
|
||||
* Get I3C device information, Retrieve I3C dev info.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - Device we want information on.
|
||||
* info - The information object to fill in.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void i3c_device_get_info(FAR const struct i3c_device *dev,
|
||||
FAR struct i3c_device_info *info)
|
||||
{
|
||||
if (!info)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
i3c_bus_normaluse_lock(dev->bus);
|
||||
if (dev->desc)
|
||||
{
|
||||
*info = dev->desc->info;
|
||||
}
|
||||
|
||||
i3c_bus_normaluse_unlock(dev->bus);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: i3c_device_disable_ibi
|
||||
*
|
||||
* Description:
|
||||
* Disable IBIs coming from a specific device.
|
||||
*
|
||||
* This function disable IBIs coming from a specific device and wait for
|
||||
* all pending IBIs to be processed.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - Device on which IBIs should be disabled
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 in case of success, a negative error core otherwise.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int i3c_device_disable_ibi(FAR const struct i3c_device *dev)
|
||||
{
|
||||
int ret = -ENOENT;
|
||||
|
||||
i3c_bus_normaluse_lock(dev->bus);
|
||||
if (dev->desc)
|
||||
{
|
||||
nxmutex_lock(&dev->desc->ibi_lock);
|
||||
ret = i3c_dev_disable_ibi_locked(dev->desc);
|
||||
nxmutex_unlock(&dev->desc->ibi_lock);
|
||||
}
|
||||
|
||||
i3c_bus_normaluse_unlock(dev->bus);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: i3c_device_enable_ibi
|
||||
*
|
||||
* Description:
|
||||
* Enable IBIs coming from a specific device.
|
||||
*
|
||||
* This function enable IBIs coming from a specific device and wait for
|
||||
* all pending IBIs to be processed. This should be called on a device
|
||||
* where i3c_device_request_ibi() has succeeded.
|
||||
*
|
||||
* Note that IBIs from this device might be received before this function
|
||||
* returns to its caller.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - Device on which IBIs should be enabled
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 in case of success, a negative error core otherwise.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int i3c_device_enable_ibi(FAR const struct i3c_device *dev)
|
||||
{
|
||||
int ret = -ENOENT;
|
||||
|
||||
i3c_bus_normaluse_lock(dev->bus);
|
||||
if (dev->desc)
|
||||
{
|
||||
nxmutex_lock(&dev->desc->ibi_lock);
|
||||
ret = i3c_dev_enable_ibi_locked(dev->desc);
|
||||
nxmutex_unlock(&dev->desc->ibi_lock);
|
||||
}
|
||||
|
||||
i3c_bus_normaluse_unlock(dev->bus);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: i3c_device_request_ibi
|
||||
*
|
||||
* Description:
|
||||
* Request an IBI.
|
||||
*
|
||||
* This function is responsible for pre-allocating all resources needed to
|
||||
* process IBIs coming from @dev. When this function returns, the IBI is
|
||||
* not enabled until i3c_device_enable_ibi() is called.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - Device for which we should enable IBIs
|
||||
* req - Setup requested for this IBI
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 in case of success, a negative error core otherwise.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int i3c_device_request_ibi(FAR const struct i3c_device *dev,
|
||||
FAR const struct i3c_ibi_setup *req)
|
||||
{
|
||||
int ret = -ENOENT;
|
||||
|
||||
if (!req->handler || !req->num_slots)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
i3c_bus_normaluse_lock(dev->bus);
|
||||
if (dev->desc)
|
||||
{
|
||||
nxmutex_lock(&dev->desc->ibi_lock);
|
||||
ret = i3c_dev_request_ibi_locked(dev->desc, req);
|
||||
nxmutex_unlock(&dev->desc->ibi_lock);
|
||||
}
|
||||
|
||||
i3c_bus_normaluse_unlock(dev->bus);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: i3c_device_free_ibi
|
||||
*
|
||||
* Description:
|
||||
* Free all resources needed for IBI handling.
|
||||
*
|
||||
* This function is responsible for de-allocating resources previously
|
||||
* allocated by i3c_device_request_ibi(). It should be called after
|
||||
* disabling IBIs with i3c_device_disable_ibi().
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - Device on which you want to release IBI resources
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void i3c_device_free_ibi(FAR const struct i3c_device *dev)
|
||||
{
|
||||
i3c_bus_normaluse_lock(dev->bus);
|
||||
if (dev->desc)
|
||||
{
|
||||
nxmutex_lock(&dev->desc->ibi_lock);
|
||||
i3c_dev_free_ibi_locked(dev->desc);
|
||||
nxmutex_unlock(&dev->desc->ibi_lock);
|
||||
}
|
||||
|
||||
i3c_bus_normaluse_unlock(dev->bus);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: i3c_master_find_i3c_dev
|
||||
*
|
||||
* Description:
|
||||
* This function is used to be find a i3c_device address by master handle
|
||||
* and provisional ID.
|
||||
*
|
||||
* Input Parameters:
|
||||
* master - The master used to get i3c_device on the bus
|
||||
* id - An instance of i3c_device_id, include manufid,partid and so on.
|
||||
*
|
||||
* Returned Value:
|
||||
* Struct i3c_device var in case of success, NULL otherwise.
|
||||
****************************************************************************/
|
||||
|
||||
FAR const struct i3c_device *i3c_master_find_i3c_dev(
|
||||
FAR struct i3c_master_controller *master,
|
||||
FAR const struct i3c_device_id *id)
|
||||
{
|
||||
FAR struct i3c_dev_desc *desc;
|
||||
uint16_t manuf;
|
||||
uint16_t part;
|
||||
uint16_t ext_info;
|
||||
bool rndpid;
|
||||
|
||||
i3c_bus_normaluse_lock(&master->bus);
|
||||
i3c_bus_for_each_i3cdev(&master->bus, desc)
|
||||
{
|
||||
manuf = I3C_PID_MANUF_ID(desc->info.pid);
|
||||
part = I3C_PID_PART_ID(desc->info.pid);
|
||||
ext_info = I3C_PID_EXTRA_INFO(desc->info.pid);
|
||||
rndpid = I3C_PID_RND_LOWER_32BITS(desc->info.pid);
|
||||
|
||||
if ((id->match_flags & I3C_MATCH_DCR) &&
|
||||
id->dcr != desc->info.dcr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((id->match_flags & I3C_MATCH_MANUF) &&
|
||||
id->manuf_id != manuf)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((id->match_flags & I3C_MATCH_PART) &&
|
||||
(rndpid || id->part_id != part))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((id->match_flags & I3C_MATCH_EXTRA_INFO) &&
|
||||
(rndpid || id->extra_info != ext_info))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
i3c_bus_normaluse_unlock(&master->bus);
|
||||
return desc->dev;
|
||||
}
|
||||
|
||||
i3c_bus_normaluse_unlock(&master->bus);
|
||||
return NULL;
|
||||
}
|
||||
398
drivers/i3c/i3c_driver.c
Normal file
398
drivers/i3c/i3c_driver.c
Normal file
|
|
@ -0,0 +1,398 @@
|
|||
/****************************************************************************
|
||||
* drivers/i3c/i3c_driver.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 <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/mutex.h>
|
||||
#include <nuttx/i3c/master.h>
|
||||
#include <nuttx/i3c/i3c_driver.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define DEVNAME_FMT "/dev/i3c%d"
|
||||
#define DEVNAME_FMTLEN (8 + 3 + 1)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* Driver state structure */
|
||||
|
||||
struct i3c_driver_s
|
||||
{
|
||||
/* Contained I3C lower half driver */
|
||||
|
||||
FAR struct i3c_master_controller *master;
|
||||
|
||||
/* Mutual exclusion */
|
||||
|
||||
mutex_t lock;
|
||||
|
||||
/* Number of open references */
|
||||
|
||||
int16_t crefs;
|
||||
|
||||
/* True, driver has been unlinked */
|
||||
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
bool unlinked;
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static int i3cdrvr_open(FAR struct file *filep);
|
||||
static int i3cdrvr_close(FAR struct file *filep);
|
||||
static ssize_t i3cdrvr_read(FAR struct file *filep, FAR char *buffer,
|
||||
size_t buflen);
|
||||
static ssize_t i3cdrvr_write(FAR struct file *filep, FAR const char *buffer,
|
||||
size_t buflen);
|
||||
static int i3cdrvr_ioctl(FAR struct file *filep, int cmd,
|
||||
unsigned long arg);
|
||||
static int i3cdrvr_unlink(FAR struct inode *inode);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static const struct file_operations g_i3cdrvr_fops =
|
||||
{
|
||||
i3cdrvr_open, /* open */
|
||||
i3cdrvr_close, /* close */
|
||||
i3cdrvr_read, /* read */
|
||||
i3cdrvr_write, /* write */
|
||||
NULL, /* seek */
|
||||
i3cdrvr_ioctl, /* ioctl */
|
||||
NULL, /* mmap */
|
||||
NULL, /* truncate */
|
||||
NULL /* poll */
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
, i3cdrvr_unlink /* unlink */
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: i3cdrvr_open
|
||||
****************************************************************************/
|
||||
|
||||
static int i3cdrvr_open(FAR struct file *filep)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
FAR struct i3c_driver_s *priv;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(filep != NULL && filep->f_inode != NULL);
|
||||
inode = filep->f_inode;
|
||||
|
||||
priv = inode->i_private;
|
||||
DEBUGASSERT(priv);
|
||||
|
||||
/* Get exclusive access to the I3C driver state structure */
|
||||
|
||||
ret = nxmutex_lock(&priv->lock);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Increment the count of open references on the driver */
|
||||
|
||||
priv->crefs++;
|
||||
DEBUGASSERT(priv->crefs > 0);
|
||||
|
||||
nxmutex_unlock(&priv->lock);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: i3cdrvr_close
|
||||
****************************************************************************/
|
||||
|
||||
static int i3cdrvr_close(FAR struct file *filep)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
FAR struct i3c_driver_s *priv;
|
||||
int ret;
|
||||
|
||||
/* Get our private data structure */
|
||||
|
||||
DEBUGASSERT(filep != NULL && filep->f_inode != NULL);
|
||||
inode = filep->f_inode;
|
||||
|
||||
priv = inode->i_private;
|
||||
DEBUGASSERT(priv);
|
||||
|
||||
/* Get exclusive access to the I3C driver state structure */
|
||||
|
||||
ret = nxmutex_lock(&priv->lock);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Decrement the count of open references on the driver */
|
||||
|
||||
DEBUGASSERT(priv->crefs > 0);
|
||||
priv->crefs--;
|
||||
|
||||
/* If the count has decremented to zero,then commit Hara-Kiri now. */
|
||||
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
if (priv->crefs <= 0 && priv->unlinked)
|
||||
#else
|
||||
if (priv->crefs <= 0)
|
||||
#endif
|
||||
{
|
||||
nxmutex_destroy(&priv->lock);
|
||||
kmm_free(priv);
|
||||
return OK;
|
||||
}
|
||||
|
||||
nxmutex_unlock(&priv->lock);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: i3cdrvr_read
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t i3cdrvr_read(FAR struct file *filep, FAR char *buffer,
|
||||
size_t len)
|
||||
{
|
||||
return 0; /* Return EOF */
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: i3cdrvr_write
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t i3cdrvr_write(FAR struct file *filep, FAR const char *buffer,
|
||||
size_t len)
|
||||
{
|
||||
return len; /* Say that everything was written */
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: i3cdrvr_ioctl
|
||||
****************************************************************************/
|
||||
|
||||
static int i3cdrvr_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
FAR struct i3c_driver_s *priv;
|
||||
FAR struct i3c_transfer_s *transfer;
|
||||
FAR struct i3c_dev_desc *desc;
|
||||
bool obtain = false;
|
||||
uint16_t manufid;
|
||||
uint16_t partid;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(filep != NULL && filep->f_inode != NULL);
|
||||
inode = filep->f_inode;
|
||||
|
||||
priv = inode->i_private;
|
||||
DEBUGASSERT(priv);
|
||||
|
||||
/* Get exclusive access to the I3C driver state structure */
|
||||
|
||||
ret = nxmutex_lock(&priv->lock);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
transfer = (FAR struct i3c_transfer_s *)((uintptr_t)arg);
|
||||
DEBUGASSERT(transfer != NULL);
|
||||
|
||||
i3c_bus_normaluse_lock(&priv->master->bus);
|
||||
i3c_bus_for_each_i3cdev(&priv->master->bus, desc)
|
||||
{
|
||||
manufid = I3C_PID_MANUF_ID(desc->info.pid);
|
||||
partid = I3C_PID_PART_ID(desc->info.pid);
|
||||
|
||||
if (manufid == transfer->manufid && partid == transfer->partid)
|
||||
{
|
||||
obtain = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
i3c_bus_normaluse_unlock(&priv->master->bus);
|
||||
if (!obtain)
|
||||
{
|
||||
nxmutex_unlock(&priv->lock);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
/* Process the IOCTL command */
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case I3CIOC_PRIV_XFERS:
|
||||
|
||||
DEBUGASSERT(transfer->xfers != NULL);
|
||||
|
||||
/* Perform the transfer */
|
||||
|
||||
ret = i3c_device_do_priv_xfers(desc->dev, transfer->xfers,
|
||||
transfer->nxfers);
|
||||
break;
|
||||
case I3CIOC_GET_DEVINFO:
|
||||
|
||||
DEBUGASSERT(transfer->info != NULL);
|
||||
|
||||
/* Perform the get specified i3c device operating */
|
||||
|
||||
i3c_device_get_info(desc->dev, transfer->info);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOTTY;
|
||||
break;
|
||||
}
|
||||
|
||||
nxmutex_unlock(&priv->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: i3cdrvr_unlink
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
static int i3cdrvr_unlink(FAR struct inode *inode)
|
||||
{
|
||||
FAR struct i3c_driver_s *priv;
|
||||
int ret;
|
||||
|
||||
/* Get our private data structure */
|
||||
|
||||
DEBUGASSERT(inode != NULL && inode->i_private != NULL);
|
||||
priv = (FAR struct i3c_driver_s *)inode->i_private;
|
||||
|
||||
/* Get exclusive access to the I3C driver state structure */
|
||||
|
||||
ret = nxmutex_lock(&priv->lock);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Are there open references to the driver data structure? */
|
||||
|
||||
if (priv->crefs <= 0)
|
||||
{
|
||||
nxmutex_destroy(&priv->lock);
|
||||
kmm_free(priv);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* No... just mark the driver as unlinked and free the resources when the
|
||||
* last client closes their reference to the driver.
|
||||
*/
|
||||
|
||||
priv->unlinked = true;
|
||||
nxmutex_unlock(&priv->lock);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: i3c_register
|
||||
*
|
||||
* Description:
|
||||
* Create and register the I3C character driver.
|
||||
*
|
||||
* The I3C character driver is a simple character driver that supports I3C
|
||||
* transfers. The intent of this driver is to support I3C testing. It is
|
||||
* not suitable for use in any real driver application.
|
||||
*
|
||||
* Input Parameters:
|
||||
* master - the lower half of an the controller object about I3C master
|
||||
* driver.
|
||||
* bus - The I3C bus number. This will be used as the I3C device minor
|
||||
* number. The I3C character device will be registered as /dev/i3cN
|
||||
* where N is the minor number
|
||||
*
|
||||
* Returned Value:
|
||||
* OK if the driver was successfully register; A negated errno value is
|
||||
* returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int i3c_register(FAR struct i3c_master_controller *master, int bus)
|
||||
{
|
||||
FAR struct i3c_driver_s *priv;
|
||||
char devname[DEVNAME_FMTLEN];
|
||||
int ret;
|
||||
|
||||
/* Sanity check */
|
||||
|
||||
DEBUGASSERT(master != NULL && (unsigned)bus < 1000);
|
||||
|
||||
priv = kmm_zalloc(sizeof(struct i3c_driver_s));
|
||||
if (priv == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
priv->master = master;
|
||||
nxmutex_init(&priv->lock);
|
||||
|
||||
/* Create the character device name */
|
||||
|
||||
snprintf(devname, sizeof(devname), DEVNAME_FMT, bus);
|
||||
ret = register_driver(devname, &g_i3cdrvr_fops, 0666, priv);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* Free the device structure if we failed to create the character
|
||||
* device.
|
||||
*/
|
||||
|
||||
nxmutex_destroy(&priv->lock);
|
||||
kmm_free(priv);
|
||||
}
|
||||
|
||||
/* Return the result of the registration */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
49
drivers/i3c/internals.h
Normal file
49
drivers/i3c/internals.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/****************************************************************************
|
||||
* drivers/i3c/internals.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 __INCLUDE_NUTTX_I3C_INTERNALS_H
|
||||
#define __INCLUDE_NUTTX_I3C_INTERNALS_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/i3c/master.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions Definitions
|
||||
****************************************************************************/
|
||||
|
||||
void i3c_bus_normaluse_lock(FAR struct i3c_bus *bus);
|
||||
void i3c_bus_normaluse_unlock(FAR struct i3c_bus *bus);
|
||||
|
||||
FAR struct i3c_master_controller *
|
||||
i3c_adapter_to_i3c_master(FAR struct i3c_master_s *i3c_master);
|
||||
|
||||
int i3c_dev_do_priv_xfers_locked(FAR struct i3c_dev_desc *dev,
|
||||
FAR struct i3c_priv_xfer *xfers,
|
||||
int nxfers);
|
||||
int i3c_dev_disable_ibi_locked(FAR struct i3c_dev_desc *dev);
|
||||
int i3c_dev_enable_ibi_locked(FAR struct i3c_dev_desc *dev);
|
||||
int i3c_dev_request_ibi_locked(FAR struct i3c_dev_desc *dev,
|
||||
FAR const struct i3c_ibi_setup *req);
|
||||
void i3c_dev_free_ibi_locked(FAR struct i3c_dev_desc *dev);
|
||||
|
||||
#endif /* __INCLUDE_NUTTX_I3C_INTERNAL_H */
|
||||
2286
drivers/i3c/master.c
Normal file
2286
drivers/i3c/master.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -596,6 +596,24 @@
|
|||
# define i2sinfo _none
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEBUG_I3C_ERROR
|
||||
# define i3cerr _err
|
||||
#else
|
||||
# define i3cerr _none
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEBUG_I3C_WARN
|
||||
# define i3cwarn _warn
|
||||
#else
|
||||
# define i3cwarn _none
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEBUG_I3C_INFO
|
||||
# define i3cinfo _info
|
||||
#else
|
||||
# define i3cinfo _none
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEBUG_PWM_ERROR
|
||||
# define pwmerr _err
|
||||
#else
|
||||
|
|
@ -1192,6 +1210,14 @@
|
|||
# define i2sinfodumpbuffer(m,b,n)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEBUG_I3C
|
||||
# define i3cerrdumpbuffer(m,b,n) errdumpbuffer(m,b,n)
|
||||
# define i3cinfodumpbuffer(m,b,n) infodumpbuffer(m,b,n)
|
||||
#else
|
||||
# define i3cerrdumpbuffer(m,b,n)
|
||||
# define i3cinfodumpbuffer(m,b,n)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEBUG_PWM
|
||||
# define pwmerrdumpbuffer(m,b,n) errdumpbuffer(m,b,n)
|
||||
# define pwminfodumpbuffer(m,b,n) infodumpbuffer(m,b,n)
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@
|
|||
#define _FFIOCBASE (0x3f00) /* Force feedback ioctl commands */
|
||||
#define _PINCTRLBASE (0x4000) /* Pinctrl driver ioctl commands */
|
||||
#define _PCIBASE (0x4100) /* Pci ioctl commands */
|
||||
#define _I3CBASE (0x4200) /* I3C driver ioctl commands */
|
||||
#define _WLIOCBASE (0x8b00) /* Wireless modules ioctl network commands */
|
||||
|
||||
/* boardctl() commands share the same number space */
|
||||
|
|
@ -726,6 +727,13 @@
|
|||
#define _PCIIOCVALID(c) (_IOC_TYPE(c)==_PCIBASE)
|
||||
#define _PCIIOC(nr) _IOC(_PCIBASE,nr)
|
||||
|
||||
/* I3C driver ioctl definitions *********************************************/
|
||||
|
||||
/* see nuttx/include/i3c/i3c_driver.h */
|
||||
|
||||
#define _I3CIOCVALID(c) (_IOC_TYPE(c)==_I3CBASE)
|
||||
#define _I3CIOC(nr) _IOC(_I3CBASE,nr)
|
||||
|
||||
/* Force Feedback driver command definitions ********************************/
|
||||
|
||||
/* see nuttx/include/input/ff.h */
|
||||
|
|
|
|||
443
include/nuttx/i3c/ccc.h
Normal file
443
include/nuttx/i3c/ccc.h
Normal file
|
|
@ -0,0 +1,443 @@
|
|||
/****************************************************************************
|
||||
* include/nuttx/i3c/ccc.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 __INCLUDE_NUTTX_I3C_CCC_H
|
||||
#define __INCLUDE_NUTTX_I3C_CCC_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <nuttx/bits.h>
|
||||
#include <nuttx/i3c/device.h>
|
||||
#include <nuttx/compiler.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* I3C CCC (Common Command Codes) related definitions */
|
||||
|
||||
#define I3C_CCC_DIRECT I3C_BIT(7)
|
||||
|
||||
#define I3C_CCC_ID(id, broadcast) \
|
||||
((id) | ((broadcast) ? 0 : I3C_CCC_DIRECT))
|
||||
|
||||
/* Commands valid in both broadcast and unicast modes */
|
||||
|
||||
#define I3C_CCC_ENEC(broadcast) I3C_CCC_ID(0x0, broadcast)
|
||||
#define I3C_CCC_DISEC(broadcast) I3C_CCC_ID(0x1, broadcast)
|
||||
#define I3C_CCC_ENTAS(as, broadcast) I3C_CCC_ID(0x2 + (as), broadcast)
|
||||
#define I3C_CCC_RSTDAA(broadcast) I3C_CCC_ID(0x6, broadcast)
|
||||
#define I3C_CCC_SETMWL(broadcast) I3C_CCC_ID(0x9, broadcast)
|
||||
#define I3C_CCC_SETMRL(broadcast) I3C_CCC_ID(0xa, broadcast)
|
||||
#define I3C_CCC_SETXTIME(broadcast) ((broadcast) ? 0x28 : 0x98)
|
||||
#define I3C_CCC_VENDOR(id, broadcast) ((id) + ((broadcast) ? 0x61 : 0xe0))
|
||||
|
||||
/* Broadcast-only commands */
|
||||
|
||||
#define I3C_CCC_ENTDAA I3C_CCC_ID(0x7, true)
|
||||
#define I3C_CCC_DEFSLVS I3C_CCC_ID(0x8, true)
|
||||
#define I3C_CCC_ENTTM I3C_CCC_ID(0xb, true)
|
||||
#define I3C_CCC_ENTHDR(x) I3C_CCC_ID(0x20 + (x), true)
|
||||
|
||||
/* Unicast-only commands */
|
||||
|
||||
#define I3C_CCC_SETDASA I3C_CCC_ID(0x7, false)
|
||||
#define I3C_CCC_SETNEWDA I3C_CCC_ID(0x8, false)
|
||||
#define I3C_CCC_GETMWL I3C_CCC_ID(0xb, false)
|
||||
#define I3C_CCC_GETMRL I3C_CCC_ID(0xc, false)
|
||||
#define I3C_CCC_GETPID I3C_CCC_ID(0xd, false)
|
||||
#define I3C_CCC_GETBCR I3C_CCC_ID(0xe, false)
|
||||
#define I3C_CCC_GETDCR I3C_CCC_ID(0xf, false)
|
||||
#define I3C_CCC_GETSTATUS I3C_CCC_ID(0x10, false)
|
||||
#define I3C_CCC_GETACCMST I3C_CCC_ID(0x11, false)
|
||||
#define I3C_CCC_SETBRGTGT I3C_CCC_ID(0x13, false)
|
||||
#define I3C_CCC_GETMXDS I3C_CCC_ID(0x14, false)
|
||||
#define I3C_CCC_GETHDRCAP I3C_CCC_ID(0x15, false)
|
||||
#define I3C_CCC_GETXTIME I3C_CCC_ID(0x19, false)
|
||||
|
||||
#define I3C_CCC_EVENT_SIR I3C_BIT(0)
|
||||
#define I3C_CCC_EVENT_MR I3C_BIT(1)
|
||||
#define I3C_CCC_EVENT_HJ I3C_BIT(3)
|
||||
|
||||
#define I3C_CCC_STATUS_PENDING_INT(status) ((status) & I3C_GENMASK(3, 0))
|
||||
#define I3C_CCC_STATUS_PROTOCOL_ERROR I3C_BIT(5)
|
||||
#define I3C_CCC_STATUS_ACTIVITY_MODE(status) \
|
||||
(((status) & I3C_GENMASK(7, 6)) >> 6)
|
||||
|
||||
#define I3C_CCC_MAX_SDR_FSCL_MASK I3C_GENMASK(2, 0)
|
||||
#define I3C_CCC_MAX_SDR_FSCL(x) ((x) & I3C_CCC_MAX_SDR_FSCL_MASK)
|
||||
|
||||
#define I3C_CCC_HDR_MODE(mode) I3C_BIT(mode)
|
||||
|
||||
#define I3C_CCC_GETXTIME_SYNC_MODE I3C_BIT(0)
|
||||
#define I3C_CCC_GETXTIME_ASYNC_MODE(x) I3C_BIT((x) + 1)
|
||||
#define I3C_CCC_GETXTIME_OVERFLOW I3C_BIT(7)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* struct i3c_ccc_events - payload passed to ENEC/DISEC CCC
|
||||
*
|
||||
* @events: bitmask of I3C_CCC_EVENT_xxx events.
|
||||
*
|
||||
* Depending on the CCC command, the specific events coming from all devices
|
||||
* (broadcast version) or a specific device (unicast version) will be
|
||||
* enabled (ENEC) or disabled (DISEC).
|
||||
*/
|
||||
|
||||
struct i3c_ccc_events
|
||||
{
|
||||
uint8_t events;
|
||||
};
|
||||
|
||||
/* struct i3c_ccc_mwl - payload passed to SETMWL/GETMWL CCC
|
||||
*
|
||||
* @len: maximum write length in bytes
|
||||
*
|
||||
* The maximum write length is only applicable to SDR private messages or
|
||||
* extended Write CCCs (like SETXTIME).
|
||||
*/
|
||||
|
||||
struct i3c_ccc_mwl
|
||||
{
|
||||
uint16_t len;
|
||||
};
|
||||
|
||||
/* struct i3c_ccc_mrl - payload passed to SETMRL/GETMRL CCC
|
||||
*
|
||||
* @len: maximum read length in bytes
|
||||
* @ibi_len: maximum IBI payload length
|
||||
*
|
||||
* The maximum read length is only applicable to SDR private messages or
|
||||
* extended Read CCCs (like GETXTIME).
|
||||
* The IBI length is only valid if the I3C slave is IBI capable
|
||||
* (%I3C_BCR_IBI_REQ_CAP is set).
|
||||
*/
|
||||
|
||||
begin_packed_struct struct i3c_ccc_mrl
|
||||
{
|
||||
uint16_t read_len;
|
||||
uint8_t ibi_len;
|
||||
} end_packed_struct;
|
||||
|
||||
/* struct i3c_ccc_dev_desc - I3C/I2C device descriptor used for DEFSLVS
|
||||
*
|
||||
* @dyn_addr: dynamic address assigned to the I3C slave or 0 if the entry is
|
||||
* describing an I2C slave.
|
||||
* @dcr: DCR value (not applicable to entries describing I2C devices)
|
||||
* @lvr: LVR value (not applicable to entries describing I3C devices)
|
||||
* @bcr: BCR value or 0 if this entry is describing an I2C slave
|
||||
* @static_addr: static address or 0 if the device does not have a static
|
||||
* address
|
||||
*
|
||||
* The DEFSLVS command should be passed an array of i3c_ccc_dev_desc
|
||||
* descriptors (one entry per I3C/I2C dev controlled by the master).
|
||||
*/
|
||||
|
||||
struct i3c_ccc_dev_desc
|
||||
{
|
||||
uint8_t dyn_addr;
|
||||
union
|
||||
{
|
||||
uint8_t dcr;
|
||||
uint8_t lvr;
|
||||
};
|
||||
uint8_t bcr;
|
||||
uint8_t static_addr;
|
||||
};
|
||||
|
||||
/* struct i3c_ccc_defslvs - payload passed to DEFSLVS CCC
|
||||
*
|
||||
* @count: number of dev descriptors
|
||||
* @master: descriptor describing the current master
|
||||
* @slaves: array of descriptors describing slaves controlled by the
|
||||
* current master
|
||||
*
|
||||
* Information passed to the broadcast DEFSLVS to propagate device
|
||||
* information to all masters currently acting as slaves on the bus.
|
||||
* This is only meaningful if you have more than one master.
|
||||
*/
|
||||
|
||||
begin_packed_struct struct i3c_ccc_defslvs
|
||||
{
|
||||
uint8_t count;
|
||||
struct i3c_ccc_dev_desc master;
|
||||
struct i3c_ccc_dev_desc slaves[0];
|
||||
} end_packed_struct;
|
||||
|
||||
/* enum i3c_ccc_test_mode - enum listing all available test modes
|
||||
*
|
||||
* @I3C_CCC_EXIT_TEST_MODE: exit test mode
|
||||
* @I3C_CCC_VENDOR_TEST_MODE: enter vendor test mode
|
||||
*/
|
||||
|
||||
enum i3c_ccc_test_mode
|
||||
{
|
||||
I3C_CCC_EXIT_TEST_MODE,
|
||||
I3C_CCC_VENDOR_TEST_MODE,
|
||||
};
|
||||
|
||||
/* struct i3c_ccc_enttm - payload passed to ENTTM CCC
|
||||
*
|
||||
* @mode: one of the &enum i3c_ccc_test_mode modes
|
||||
*
|
||||
* Information passed to the ENTTM CCC to instruct an I3C device to enter a
|
||||
* specific test mode.
|
||||
*/
|
||||
|
||||
struct i3c_ccc_enttm
|
||||
{
|
||||
uint8_t mode;
|
||||
};
|
||||
|
||||
/* struct i3c_ccc_setda - payload passed to SETNEWDA and SETDASA CCCs
|
||||
*
|
||||
* @addr: dynamic address to assign to an I3C device
|
||||
*
|
||||
* Information passed to the SETNEWDA and SETDASA CCCs to assign/change the
|
||||
* dynamic address of an I3C device.
|
||||
*/
|
||||
|
||||
struct i3c_ccc_setda
|
||||
{
|
||||
uint8_t addr;
|
||||
};
|
||||
|
||||
/* struct i3c_ccc_getpid - payload passed to GETPID CCC
|
||||
*
|
||||
* @pid: 48 bits PID in big endian
|
||||
*/
|
||||
|
||||
struct i3c_ccc_getpid
|
||||
{
|
||||
uint8_t pid[6];
|
||||
};
|
||||
|
||||
/* struct i3c_ccc_getbcr - payload passed to GETBCR CCC
|
||||
*
|
||||
* @bcr: BCR (Bus Characteristic Register) value
|
||||
*/
|
||||
|
||||
struct i3c_ccc_getbcr
|
||||
{
|
||||
uint8_t bcr;
|
||||
};
|
||||
|
||||
/* struct i3c_ccc_getdcr - payload passed to GETDCR CCC
|
||||
*
|
||||
* @dcr: DCR (Device Characteristic Register) value
|
||||
*/
|
||||
|
||||
struct i3c_ccc_getdcr
|
||||
{
|
||||
uint8_t dcr;
|
||||
};
|
||||
|
||||
/* struct i3c_ccc_getstatus - payload passed to GETSTATUS CCC
|
||||
*
|
||||
* @status: status of the I3C slave (see I3C_CCC_STATUS_xxx macros for more
|
||||
* information).
|
||||
*/
|
||||
|
||||
struct i3c_ccc_getstatus
|
||||
{
|
||||
uint16_t status;
|
||||
};
|
||||
|
||||
/* struct i3c_ccc_getaccmst - payload passed to GETACCMST CCC
|
||||
*
|
||||
* @newmaster: address of the master taking bus ownership
|
||||
*/
|
||||
|
||||
struct i3c_ccc_getaccmst
|
||||
{
|
||||
uint8_t newmaster;
|
||||
};
|
||||
|
||||
/* struct i3c_ccc_bridged_slave_desc - bridged slave descriptor
|
||||
*
|
||||
* @addr: dynamic address of the bridged device
|
||||
* @id: ID of the slave device behind the bridge
|
||||
*/
|
||||
|
||||
begin_packed_struct struct i3c_ccc_bridged_slave_desc
|
||||
{
|
||||
uint8_t addr;
|
||||
uint16_t id;
|
||||
} end_packed_struct;
|
||||
|
||||
/* struct i3c_ccc_setbrgtgt - payload passed to SETBRGTGT CCC
|
||||
*
|
||||
* @count: number of bridged slaves
|
||||
* @bslaves: bridged slave descriptors
|
||||
*/
|
||||
|
||||
begin_packed_struct struct i3c_ccc_setbrgtgt
|
||||
{
|
||||
uint8_t count;
|
||||
struct i3c_ccc_bridged_slave_desc bslaves[0];
|
||||
} end_packed_struct;
|
||||
|
||||
/* enum i3c_sdr_max_data_rate - max data rate values for private
|
||||
* SDR transfers
|
||||
*/
|
||||
|
||||
enum i3c_sdr_max_data_rate
|
||||
{
|
||||
I3C_SDR0_FSCL_MAX,
|
||||
I3C_SDR1_FSCL_8MHZ,
|
||||
I3C_SDR2_FSCL_6MHZ,
|
||||
I3C_SDR3_FSCL_4MHZ,
|
||||
I3C_SDR4_FSCL_2MHZ,
|
||||
};
|
||||
|
||||
/* enum i3c_tsco - clock to data turn-around */
|
||||
|
||||
enum i3c_tsco
|
||||
{
|
||||
I3C_TSCO_8NS,
|
||||
I3C_TSCO_9NS,
|
||||
I3C_TSCO_10NS,
|
||||
I3C_TSCO_11NS,
|
||||
I3C_TSCO_12NS,
|
||||
};
|
||||
|
||||
/* struct i3c_ccc_getmxds - payload passed to GETMXDS CCC
|
||||
*
|
||||
* @maxwr: write limitations
|
||||
* @maxrd: read limitations
|
||||
* @maxrdturn: maximum read turn-around expressed micro-seconds and
|
||||
* little-endian formatted
|
||||
*/
|
||||
|
||||
begin_packed_struct struct i3c_ccc_getmxds
|
||||
{
|
||||
uint8_t maxwr;
|
||||
uint8_t maxrd;
|
||||
uint8_t maxrdturn[3];
|
||||
} end_packed_struct;
|
||||
|
||||
/* struct i3c_ccc_gethdrcap - payload passed to GETHDRCAP CCC
|
||||
*
|
||||
* @modes: bitmap of supported HDR modes
|
||||
*/
|
||||
|
||||
begin_packed_struct struct i3c_ccc_gethdrcap
|
||||
{
|
||||
uint8_t modes;
|
||||
} end_packed_struct;
|
||||
|
||||
/* enum i3c_ccc_setxtime_subcmd - SETXTIME sub-commands */
|
||||
|
||||
enum i3c_ccc_setxtime_subcmd
|
||||
{
|
||||
I3C_CCC_SETXTIME_ST = 0x7f,
|
||||
I3C_CCC_SETXTIME_DT = 0xbf,
|
||||
I3C_CCC_SETXTIME_ENTER_ASYNC_MODE0 = 0xdf,
|
||||
I3C_CCC_SETXTIME_ENTER_ASYNC_MODE1 = 0xef,
|
||||
I3C_CCC_SETXTIME_ENTER_ASYNC_MODE2 = 0xf7,
|
||||
I3C_CCC_SETXTIME_ENTER_ASYNC_MODE3 = 0xfb,
|
||||
I3C_CCC_SETXTIME_ASYNC_TRIGGER = 0xfd,
|
||||
I3C_CCC_SETXTIME_TPH = 0x3f,
|
||||
I3C_CCC_SETXTIME_TU = 0x9f,
|
||||
I3C_CCC_SETXTIME_ODR = 0x8f,
|
||||
};
|
||||
|
||||
/* struct i3c_ccc_setxtime - payload passed to SETXTIME CCC
|
||||
*
|
||||
* @subcmd: one of the sub-commands ddefined in &enum i3c_ccc_setxtime_subcmd
|
||||
* @data: sub-command payload. Amount of data is determined by
|
||||
* &i3c_ccc_setxtime->subcmd
|
||||
*/
|
||||
|
||||
begin_packed_struct struct i3c_ccc_setxtime
|
||||
{
|
||||
uint8_t subcmd;
|
||||
uint8_t data[0];
|
||||
} end_packed_struct;
|
||||
|
||||
/* struct i3c_ccc_getxtime - payload retrieved from GETXTIME CCC
|
||||
*
|
||||
* @supported_modes: bitmap describing supported XTIME modes
|
||||
* @state: current status (enabled mode and overflow status)
|
||||
* @frequency: slave's internal oscillator frequency in 500KHz steps
|
||||
* @inaccuracy: slave's internal oscillator inaccuracy in 0.1% steps
|
||||
*/
|
||||
|
||||
begin_packed_struct struct i3c_ccc_getxtime
|
||||
{
|
||||
uint8_t supported_modes;
|
||||
uint8_t state;
|
||||
uint8_t frequency;
|
||||
uint8_t inaccuracy;
|
||||
}end_packed_struct;
|
||||
|
||||
/* struct i3c_ccc_cmd_payload - CCC payload
|
||||
*
|
||||
* @len: payload length
|
||||
* @data: payload data. This buffer must be DMA-able
|
||||
*/
|
||||
|
||||
struct i3c_ccc_cmd_payload
|
||||
{
|
||||
uint16_t len;
|
||||
FAR void *data;
|
||||
};
|
||||
|
||||
/* struct i3c_ccc_cmd_dest - CCC command destination
|
||||
*
|
||||
* @addr: can be an I3C device address or the broadcast address if this is a
|
||||
* broadcast CCC
|
||||
* @payload: payload to be sent to this device or broadcasted
|
||||
*/
|
||||
|
||||
struct i3c_ccc_cmd_dest
|
||||
{
|
||||
uint8_t addr;
|
||||
struct i3c_ccc_cmd_payload payload;
|
||||
};
|
||||
|
||||
/* struct i3c_ccc_cmd - CCC command
|
||||
*
|
||||
* @rnw: true if the CCC should retrieve data from the device. Only valid
|
||||
* for unicast commands
|
||||
* @id: CCC command id
|
||||
* @ndests: number of destinations. Should always be one for broadcast
|
||||
* commands
|
||||
* @dests: array of destinations and associated payload for this CCC. Most
|
||||
* of the time, only one destination is provided
|
||||
* @err: I3C error code
|
||||
*/
|
||||
|
||||
struct i3c_ccc_cmd
|
||||
{
|
||||
uint8_t rnw;
|
||||
uint8_t id;
|
||||
unsigned int ndests;
|
||||
FAR struct i3c_ccc_cmd_dest *dests;
|
||||
enum i3c_error_code err;
|
||||
};
|
||||
|
||||
#endif /* __INCLUDE_NUTTX_I3C_CCC_H */
|
||||
420
include/nuttx/i3c/device.h
Normal file
420
include/nuttx/i3c/device.h
Normal file
|
|
@ -0,0 +1,420 @@
|
|||
/****************************************************************************
|
||||
* include/nuttx/i3c/device.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 __INCLUDE_NUTTX_I3C_DEV_H
|
||||
#define __INCLUDE_NUTTX_I3C_DEV_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/list.h>
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
#include <nuttx/i3c/i3c_driver.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define I3C_PID_MANUF_ID(pid) (((pid) & I3C_GENMASK_ULL(47, 33)) >> 33)
|
||||
#define I3C_PID_RND_LOWER_32BITS(pid) (!!((pid) & BIT_ULL(32)))
|
||||
#define I3C_PID_RND_VAL(pid) ((pid) & I3C_GENMASK_ULL(31, 0))
|
||||
#define I3C_PID_PART_ID(pid) (((pid) & I3C_GENMASK_ULL(31, 16)) >> 16)
|
||||
#define I3C_PID_INSTANCE_ID(pid) (((pid) & I3C_GENMASK_ULL(15, 12)) >> 12)
|
||||
#define I3C_PID_EXTRA_INFO(pid) ((pid) & I3C_GENMASK_ULL(11, 0))
|
||||
|
||||
#define I3C_BCR_DEVICE_ROLE(bcr) ((bcr) & I3C_GENMASK(7, 6))
|
||||
#define I3C_BCR_I3C_SLAVE (0 << 6)
|
||||
#define I3C_BCR_I3C_MASTER (1 << 6)
|
||||
#define I3C_BCR_HDR_CAP I3C_BIT(5)
|
||||
#define I3C_BCR_BRIDGE I3C_BIT(4)
|
||||
#define I3C_BCR_OFFLINE_CAP I3C_BIT(3)
|
||||
#define I3C_BCR_IBI_PAYLOAD I3C_BIT(2)
|
||||
#define I3C_BCR_IBI_REQ_CAP I3C_BIT(1)
|
||||
#define I3C_BCR_MAX_DATA_SPEED_LIM I3C_BIT(0)
|
||||
|
||||
/* i3c */
|
||||
|
||||
#define I3C_MATCH_DCR 0x1
|
||||
#define I3C_MATCH_MANUF 0x2
|
||||
#define I3C_MATCH_PART 0x4
|
||||
#define I3C_MATCH_EXTRA_INFO 0x8
|
||||
|
||||
/* These macros should be used to i3c_device_id entries. */
|
||||
|
||||
#define I3C_MATCH_MANUF_AND_PART (I3C_MATCH_MANUF | I3C_MATCH_PART)
|
||||
|
||||
#define I3C_DEVICE(_manufid, _partid, _drvdata) \
|
||||
{ \
|
||||
.match_flags = I3C_MATCH_MANUF_AND_PART, \
|
||||
.manuf_id = _manufid, \
|
||||
.part_id = _partid, \
|
||||
.data = _drvdata, \
|
||||
}
|
||||
|
||||
#define I3C_DEVICE_EXTRA_INFO(_manufid, _partid, _info, _drvdata) \
|
||||
{ \
|
||||
.match_flags = I3C_MATCH_MANUF_AND_PART | \
|
||||
I3C_MATCH_EXTRA_INFO, \
|
||||
.manuf_id = _manufid, \
|
||||
.part_id = _partid, \
|
||||
.extra_info = _info, \
|
||||
.data = _drvdata, \
|
||||
}
|
||||
|
||||
#define I3C_CLASS(_dcr, _drvdata) \
|
||||
{ \
|
||||
.match_flags = I3C_MATCH_DCR, \
|
||||
.dcr = _dcr, \
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
struct i3c_device;
|
||||
|
||||
struct i3c_device_id
|
||||
{
|
||||
uint8_t match_flags;
|
||||
uint8_t dcr;
|
||||
uint16_t manuf_id;
|
||||
uint16_t part_id;
|
||||
uint16_t extra_info;
|
||||
|
||||
FAR const void *data;
|
||||
};
|
||||
|
||||
/* enum i3c_error_code - I3C error codes
|
||||
*
|
||||
* These are the standard error codes as defined by the I3C specification.
|
||||
* When -EIO is returned by the i3c_device_do_priv_xfers() or
|
||||
* i3c_device_send_hdr_cmds() one can check the error code in
|
||||
* &struct_i3c_priv_xfer.err or &struct i3c_hdr_cmd.err to get a better
|
||||
* idea of what went wrong.
|
||||
*
|
||||
* @I3C_ERROR_UNKNOWN: unknown error, usually means the error is not I3C
|
||||
* related
|
||||
* @I3C_ERROR_M0: M0 error
|
||||
* @I3C_ERROR_M1: M1 error
|
||||
* @I3C_ERROR_M2: M2 error
|
||||
*/
|
||||
|
||||
enum i3c_error_code
|
||||
{
|
||||
I3C_ERROR_UNKNOWN = 0,
|
||||
I3C_ERROR_M0 = 1,
|
||||
I3C_ERROR_M1,
|
||||
I3C_ERROR_M2,
|
||||
};
|
||||
|
||||
/* enum i3c_hdr_mode - HDR mode ids
|
||||
* @I3C_HDR_DDR: DDR mode
|
||||
* @I3C_HDR_TSP: TSP mode
|
||||
* @I3C_HDR_TSL: TSL mode
|
||||
*/
|
||||
|
||||
enum i3c_hdr_mode
|
||||
{
|
||||
I3C_HDR_DDR,
|
||||
I3C_HDR_TSP,
|
||||
I3C_HDR_TSL,
|
||||
};
|
||||
|
||||
/* struct i3c_priv_xfer - I3C SDR private transfer
|
||||
* @rnw: encodes the transfer direction. true for a read, false for a write
|
||||
* @len: transfer length in bytes of the transfer
|
||||
* @data: input/output buffer
|
||||
* @data.in: input buffer. Must point to a DMA-able buffer
|
||||
* @data.out: output buffer. Must point to a DMA-able buffer
|
||||
* @err: I3C error code
|
||||
*/
|
||||
|
||||
struct i3c_priv_xfer
|
||||
{
|
||||
unsigned char rnw;
|
||||
uint16_t len;
|
||||
union
|
||||
{
|
||||
FAR void *in;
|
||||
FAR const void *out;
|
||||
} data;
|
||||
enum i3c_error_code err;
|
||||
};
|
||||
|
||||
/* enum i3c_dcr - I3C DCR values
|
||||
* @I3C_DCR_GENERIC_DEVICE: generic I3C device
|
||||
*/
|
||||
|
||||
enum i3c_dcr
|
||||
{
|
||||
I3C_DCR_GENERIC_DEVICE = 0,
|
||||
};
|
||||
|
||||
/* struct i3c_device_info - I3C device information
|
||||
* @pid: Provisional ID
|
||||
* @bcr: Bus Characteristic Register
|
||||
* @dcr: Device Characteristic Register
|
||||
* @static_addr: static/I2C address
|
||||
* @dyn_addr: dynamic address
|
||||
* @hdr_cap: supported HDR modes
|
||||
* @max_read_ds: max read speed information
|
||||
* @max_write_ds: max write speed information
|
||||
* @max_ibi_len: max IBI payload length
|
||||
* @max_read_turnaround: max read turn-around time in micro-seconds
|
||||
* @max_read_len: max private SDR read length in bytes
|
||||
* @max_write_len: max private SDR write length in bytes
|
||||
*
|
||||
* These are all basic information that should be advertised by an I3C
|
||||
* device.
|
||||
* Some of them are optional depending on the device type and device
|
||||
* capabilities.
|
||||
* For each I3C slave attached to a master with
|
||||
* i3c_master_add_i3c_dev_locked(), the core will send the relevant CCC
|
||||
* command to retrieve these data.
|
||||
*/
|
||||
|
||||
struct i3c_device_info
|
||||
{
|
||||
uint64_t pid;
|
||||
uint8_t bcr;
|
||||
uint8_t dcr;
|
||||
uint8_t static_addr;
|
||||
uint8_t dyn_addr;
|
||||
uint8_t hdr_cap;
|
||||
uint8_t max_read_ds;
|
||||
uint8_t max_write_ds;
|
||||
uint8_t max_ibi_len;
|
||||
uint32_t max_read_turnaround;
|
||||
uint16_t max_read_len;
|
||||
uint16_t max_write_len;
|
||||
};
|
||||
|
||||
/* I3C device internals are kept hidden from I3C device users. It's just
|
||||
* simpler to refactor things when everything goes through getter/setters,
|
||||
* and I3C device drivers should not have to worry about internal
|
||||
* representation anyway.
|
||||
*/
|
||||
|
||||
struct i3c_ibi_payload
|
||||
{
|
||||
unsigned int len;
|
||||
FAR const void *data;
|
||||
};
|
||||
|
||||
/* struct i3c_ibi_setup - IBI setup object
|
||||
* @max_payload_len: maximum length of the payload associated to an IBI.
|
||||
* If one IBI appears to have a payload that is bigger than this
|
||||
* number, the IBI will be rejected.
|
||||
* @num_slots: number of pre-allocated IBI slots. This should be chosen so
|
||||
* that the system never runs out of IBI slots, otherwise you'll
|
||||
* lose IBIs.
|
||||
* @handler: IBI handler, every time an IBI is received. This handler is
|
||||
* called in a workqueue context. It is allowed to sleep and send new
|
||||
* messages on the bus, though it's recommended to keep the
|
||||
* processing done there as fast as possible to avoid delaying
|
||||
* processing of other queued on the same workqueue.
|
||||
*
|
||||
* Temporary structure used to pass information to i3c_device_request_ibi().
|
||||
* This object can be allocated on the stack since i3c_device_request_ibi()
|
||||
* copies every bit of information and do not use it after
|
||||
* i3c_device_request_ibi() has returned.
|
||||
*/
|
||||
|
||||
struct i3c_ibi_setup
|
||||
{
|
||||
unsigned int max_payload_len;
|
||||
unsigned int num_slots;
|
||||
CODE void (*handler)(FAR struct i3c_device *dev,
|
||||
FAR const struct i3c_ibi_payload *payload);
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: i3c_device_do_priv_xfers
|
||||
*
|
||||
* Description:
|
||||
* Do I3C SDR private transfers directed to a specific device.
|
||||
*
|
||||
* Initiate one or several private SDR transfers with @dev.
|
||||
*
|
||||
* This function can sleep and thus cannot be called in atomic context.
|
||||
*
|
||||
* Input Parameters:
|
||||
* desc - An I3C device descriptor will be used for
|
||||
* xfers - Array of transfers
|
||||
* nxfers - Number of transfers
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 in case of success, a negative error core otherwise.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int i3c_device_do_priv_xfers(FAR const struct i3c_device *dev,
|
||||
FAR struct i3c_priv_xfer *xfers,
|
||||
int nxfers);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: i3c_device_get_info
|
||||
* get I3C device information, Retrieve I3C dev info.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - A device we want information on.
|
||||
* info - The information object to fill in.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void i3c_device_get_info(FAR const struct i3c_device *dev,
|
||||
FAR struct i3c_device_info *info);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: i3c_device_disable_ibi
|
||||
*
|
||||
* Description:
|
||||
* Disable IBIs coming from a specific device.
|
||||
*
|
||||
* This function disable IBIs coming from a specific device and wait for
|
||||
* all pending IBIs to be processed.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - A device on which IBIs should be disabled
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 in case of success, a negative error core otherwise.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int i3c_device_disable_ibi(FAR const struct i3c_device *dev);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: i3c_device_enable_ibi
|
||||
*
|
||||
* Description:
|
||||
* Enable IBIs coming from a specific device.
|
||||
*
|
||||
* This function enable IBIs coming from a specific device and wait for
|
||||
* all pending IBIs to be processed. This should be called on a device
|
||||
* where i3c_device_request_ibi() has succeeded.
|
||||
*
|
||||
* Note that IBIs from this device might be received before this function
|
||||
* returns to its caller.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - A device on which IBIs should be enabled
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 in case of success, a negative error core otherwise.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int i3c_device_enable_ibi(FAR const struct i3c_device *dev);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: i3c_device_request_ibi
|
||||
*
|
||||
* Description:
|
||||
* Request an IBI.
|
||||
*
|
||||
* This function is responsible for pre-allocating all resources needed to
|
||||
* process IBIs coming from @dev. When this function returns, the IBI is
|
||||
* not enabled until i3c_device_enable_ibi() is called.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - An I3C device descriptor will be used for.
|
||||
* req - setup requested for this IBI.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 in case of success, a negative error core otherwise.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int i3c_device_request_ibi(FAR const struct i3c_device *dev,
|
||||
FAR const struct i3c_ibi_setup *req);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: i3c_device_free_ibi
|
||||
*
|
||||
* Description:
|
||||
* Free all resources needed for IBI handling.
|
||||
*
|
||||
* This function is responsible for de-allocating resources previously
|
||||
* allocated by i3c_device_request_ibi(). It should be called after
|
||||
* disabling IBIs with i3c_device_disable_ibi().
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - Device on which you want to release IBI resources
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void i3c_device_free_ibi(FAR const struct i3c_device *dev);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: i3c_master_i2c_attach
|
||||
*
|
||||
* Description:
|
||||
* Config an i2c device address to controller driver.
|
||||
*
|
||||
* Input Parameters:
|
||||
* master - The master used to get i3c_device on the bus
|
||||
* config - An i2c device information to add
|
||||
*
|
||||
* Returned Value:
|
||||
* Return 0 if success, otherwise a negative number.
|
||||
****************************************************************************/
|
||||
|
||||
int i3c_master_i2c_attach(FAR struct i3c_master_controller *master,
|
||||
FAR struct i2c_config_s *config);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: i3c_master_detach_i2c_dev
|
||||
*
|
||||
* Description:
|
||||
* Delete an i2c device address in controller driver. .
|
||||
*
|
||||
* Input Parameters:
|
||||
* master - The master used to get i3c_device on the bus
|
||||
* config - An i2c device information to delete
|
||||
****************************************************************************/
|
||||
|
||||
void i3c_master_detach_i2c_dev(FAR struct i3c_master_controller *master,
|
||||
FAR struct i2c_config_s *config);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: i3c_master_find_i3c_dev
|
||||
*
|
||||
* Description:
|
||||
* This function is used to be find a i3c_device address by master handle
|
||||
* and provisional ID.
|
||||
*
|
||||
* Input Parameters:
|
||||
* master - The master used to get i3c_device on the bus
|
||||
* id - An instance of i3c_device_id, include manufid,partid and so on.
|
||||
* Returned Value:
|
||||
* Struct i3c_device var in case of success, NULL otherwise.
|
||||
****************************************************************************/
|
||||
|
||||
FAR const struct i3c_device *i3c_master_find_i3c_dev(
|
||||
FAR struct i3c_master_controller *master,
|
||||
FAR const struct i3c_device_id *id);
|
||||
|
||||
#endif /* __INCLUDE_NUTTX_I3C_DEV_H */
|
||||
177
include/nuttx/i3c/i3c_driver.h
Normal file
177
include/nuttx/i3c/i3c_driver.h
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
/****************************************************************************
|
||||
* include/nuttx/i3c/i3c_driver.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 _INCLUDE_NUTTX_I3C_DRIVER_H
|
||||
#define _INCLUDE_NUTTX_I3C_DRIVER_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
#include <nuttx/i3c/device.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* I3C Character Driver IOCTL Commands **************************************/
|
||||
|
||||
/* The I3C driver is intended to support application testing of the I3C bus.
|
||||
* The I3C driver simply wraps an instance of struct i3c_driver_s and then
|
||||
* provides the following IOCTL commands to access each method of the I3c
|
||||
* interface.
|
||||
*/
|
||||
|
||||
/* Command: I3CIOC_PRIV_XFERS
|
||||
* Description: Perform an I3C transfer
|
||||
* Argument: A reference to an instance of struct i3c_transfer_s.
|
||||
* Dependencies:
|
||||
*/
|
||||
|
||||
#define I3CIOC_PRIV_XFERS _I3CIOC(0x0001)
|
||||
|
||||
/* Command: I3CIOC_EN_IBI
|
||||
* Description: Perform an I3C bus IBI enabled operation
|
||||
*
|
||||
* Argument: None
|
||||
* Dependencies:
|
||||
*/
|
||||
|
||||
#define I3CIOC_EN_IBI _I3CIOC(0x0002)
|
||||
|
||||
/* Command: I3CIOC_DIS_IBI
|
||||
* Description: Perform an I3C bus IBI disabled operation
|
||||
*
|
||||
* Argument: None
|
||||
* Dependencies:
|
||||
*/
|
||||
|
||||
#define I3CIOC_DIS_IBI _I3CIOC(0x0003)
|
||||
|
||||
/* Command: I3CIOC_REQ_IBI
|
||||
* Description: Perform an I3C bus IBI requested operation
|
||||
*
|
||||
* Argument: None
|
||||
* Dependencies:
|
||||
*/
|
||||
|
||||
#define I3CIOC_REQ_IBI _I3CIOC(0x0004)
|
||||
|
||||
/* Command: I3CIOC_FREE_IBI
|
||||
* Description: Perform an I3C bus IBI free operation
|
||||
*
|
||||
* Argument: None
|
||||
* Dependencies:
|
||||
*/
|
||||
|
||||
#define I3CIOC_FREE_IBI _I3CIOC(0x0005)
|
||||
|
||||
/* Command: I3CIOC_GET_DEVINFO
|
||||
* Description: Get an I3C bus dev infomation
|
||||
*
|
||||
* Argument: None
|
||||
* Dependencies:
|
||||
*/
|
||||
|
||||
#define I3CIOC_GET_DEVINFO _I3CIOC(0x0006)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
struct i3c_master_s;
|
||||
struct i3c_priv_xfer;
|
||||
struct i3c_ibi_setup;
|
||||
struct i3c_master_controller;
|
||||
|
||||
/* This structure is used to communicate with the I3C character driver in
|
||||
* order to perform IOCTL transfers.
|
||||
*/
|
||||
|
||||
struct i3c_transfer_s
|
||||
{
|
||||
/* manufID and partID is used to attach to i3c_dev_desc, it's */
|
||||
|
||||
uint16_t manufid;
|
||||
uint16_t partid;
|
||||
|
||||
/* Number of messages in the array. */
|
||||
|
||||
size_t nxfers;
|
||||
|
||||
/* Array of I3C messages for the transfer */
|
||||
|
||||
FAR struct i3c_priv_xfer *xfers;
|
||||
|
||||
FAR struct i3c_ibi_setup *req;
|
||||
|
||||
/* I3C device information */
|
||||
|
||||
FAR struct i3c_device_info *info;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: i3c_register
|
||||
*
|
||||
* Description:
|
||||
* Create and register the I3C character driver.
|
||||
*
|
||||
* The I3C character driver is a simple character driver that supports I3C
|
||||
* transfers. The intent of this driver is to support I3C testing. It is
|
||||
* not suitable for use in any real driver application.
|
||||
*
|
||||
* Input Parameters:
|
||||
* master - An instance of the lower half I3C core driver.
|
||||
* bus - The I3C bus number. This will be used as the I3C device minor
|
||||
* number.The I3C character device will be registered as /dev/i3cN
|
||||
* where N is the minor number.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK if the driver was successfully register; A negated errno value is
|
||||
* returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_I3C_DRIVER
|
||||
int i3c_register(FAR struct i3c_master_controller *master, int bus);
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif /* _INCLUDE_NUTTX_I3C_DRIVER_H */
|
||||
1150
include/nuttx/i3c/master.h
Normal file
1150
include/nuttx/i3c/master.h
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue