438 lines
14 KiB
C
438 lines
14 KiB
C
/****************************************************************************
|
|
* 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_ccc_cmd;
|
|
|
|
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);
|
|
|
|
/****************************************************************************
|
|
* Name: i3c_device_send_ccc_cmd
|
|
*
|
|
* Description:
|
|
* This function is used to send a common ccc command.
|
|
*
|
|
* Input Parameters:
|
|
* dev - An I3C device descriptor will be used for
|
|
* cmd - The buf of ccc commands to transfer, only one frame at a time
|
|
*
|
|
* Returned Value:
|
|
* 0 or positive if Success, nagative otherwise.
|
|
****************************************************************************/
|
|
|
|
int i3c_device_send_ccc_cmd(FAR const struct i3c_device *dev,
|
|
FAR struct i3c_ccc_cmd *cmd);
|
|
|
|
#endif /* __INCLUDE_NUTTX_I3C_DEV_H */
|