blob: 033e2038ad69420e2751b8bd63236fa4d6f5d011 [file] [log] [blame]
/*
* Copyright 2022 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_DRIVERS_I3C_CCC_H_
#define ZEPHYR_INCLUDE_DRIVERS_I3C_CCC_H_
/**
* @brief I3C Common Command Codes
* @defgroup i3c_ccc I3C Common Command Codes
* @ingroup i3c_interface
* @{
*/
#include <zephyr/types.h>
#include <zephyr/device.h>
#include <zephyr/toolchain.h>
#include <zephyr/sys/util.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Maximum CCC ID for broadcast */
#define I3C_CCC_BROADCAST_MAX_ID 0x7FU
/**
* Enable Events Command
*
* @param broadcast True if broadcast, false if direct.
*/
#define I3C_CCC_ENEC(broadcast) ((broadcast) ? 0x00U : 0x80U)
/**
* Disable Events Command
*
* @param broadcast True if broadcast, false if direct.
*/
#define I3C_CCC_DISEC(broadcast) ((broadcast) ? 0x01U : 0x81U)
/**
* Enter Activity State
*
* @param as Desired activity state
* @param broadcast True if broadcast, false if direct.
*/
#define I3C_CCC_ENTAS(as, broadcast) (((broadcast) ? 0x02U : 0x82U) + (as))
/**
* Enter Activity State 0
*
* @param broadcast True if broadcast, false if direct.
*/
#define I3C_CCC_ENTAS0(broadcast) I3C_CCC_ENTAS(0, broadcast)
/**
* Enter Activity State 1
*
* @param broadcast True if broadcast, false if direct.
*/
#define I3C_CCC_ENTAS1(broadcast) I3C_CCC_ENTAS(1, broadcast)
/**
* Enter Activity State 2
*
* @param broadcast True if broadcast, false if direct.
*/
#define I3C_CCC_ENTAS2(broadcast) I3C_CCC_ENTAS(2, broadcast)
/**
* Enter Activity State 3
*
* @param broadcast True if broadcast, false if direct.
*/
#define I3C_CCC_ENTAS3(broadcast) I3C_CCC_ENTAS(3, broadcast)
/** Reset Dynamic Address Assignment (Broadcast) */
#define I3C_CCC_RSTDAA 0x06U
/** Enter Dynamic Address Assignment (Broadcast) */
#define I3C_CCC_ENTDAA 0x07U
/** Define List of Targets (Broadcast) */
#define I3C_CCC_DEFTGTS 0x08U
/**
* Set Max Write Length (Broadcast or Direct)
*
* @param broadcast True if broadcast, false if direct.
*/
#define I3C_CCC_SETMWL(broadcast) ((broadcast) ? 0x09U : 0x89U)
/**
* Set Max Read Length (Broadcast or Direct)
*
* @param broadcast True if broadcast, false if direct.
*/
#define I3C_CCC_SETMRL(broadcast) ((broadcast) ? 0x0AU : 0x8AU)
/** Enter Test Mode (Broadcast) */
#define I3C_CCC_ENTTM 0x0BU
/** Set Bus Context (Broadcast) */
#define I3C_CCC_SETBUSCON 0x0CU
/**
* Data Transfer Ending Procedure Control
*
* @param broadcast True if broadcast, false if direct.
*/
#define I3C_CCC_ENDXFER(broadcast) ((broadcast) ? 0x12U : 0x92U)
/** Enter HDR Mode (HDR-DDR) (Broadcast) */
#define I3C_CCC_ENTHDR(x) (0x20U + (x))
/** Enter HDR Mode 0 (HDR-DDR) (Broadcast) */
#define I3C_CCC_ENTHDR0 0x20U
/** Enter HDR Mode 1 (HDR-TSP) (Broadcast) */
#define I3C_CCC_ENTHDR1 0x21U
/** Enter HDR Mode 2 (HDR-TSL) (Broadcast) */
#define I3C_CCC_ENTHDR2 0x22U
/** Enter HDR Mode 3 (HDR-BT) (Broadcast) */
#define I3C_CCC_ENTHDR3 0x23U
/** Enter HDR Mode 4 (Broadcast) */
#define I3C_CCC_ENTHDR4 0x24U
/** Enter HDR Mode 5 (Broadcast) */
#define I3C_CCC_ENTHDR5 0x25U
/** Enter HDR Mode 6 (Broadcast) */
#define I3C_CCC_ENTHDR6 0x26U
/** Enter HDR Mode 7 (Broadcast) */
#define I3C_CCC_ENTHDR7 0x27U
/**
* Exchange Timing Information (Broadcast or Direct)
*
* @param broadcast True if broadcast, false if direct.
*/
#define I3C_CCC_SETXTIME(broadcast) ((broadcast) ? 0x28U : 0x98U)
/** Set All Addresses to Static Addresses (Broadcast) */
#define I3C_CCC_SETAASA 0x29U
/**
* Target Reset Action
*
* @param broadcast True if broadcast, false if direct.
*/
#define I3C_CCC_RSTACT(broadcast) ((broadcast) ? 0x2AU : 0x9AU)
/** Define List of Group Address (Broadcast) */
#define I3C_CCC_DEFGRPA 0x2BU
/**
* Reset Group Address
*
* @param broadcast True if broadcast, false if direct.
*/
#define I3C_CCC_RSTGRPA(broadcast) ((broadcast) ? 0x2CU : 0x9CU)
/** Multi-Lane Data Transfer Control (Broadcast) */
#define I3C_CCC_MLANE(broadcast) ((broadcast) ? 0x2DU : 0x9DU)
/**
* Vendor/Standard Extension
*
* @param broadcast True if broadcast, false if direct.
* @param id Extension ID.
*/
#define I3C_CCC_VENDOR(broadcast, id) ((id) + ((broadcast) ? 0x61U : 0xE0U))
/** Set Dynamic Address from Static Address (Direct) */
#define I3C_CCC_SETDASA 0x87U
/** Set New Dynamic Address (Direct) */
#define I3C_CCC_SETNEWDA 0x88U
/** Get Max Write Length (Direct) */
#define I3C_CCC_GETMWL 0x8BU
/** Get Max Read Length (Direct) */
#define I3C_CCC_GETMRL 0x8CU
/** Get Provisioned ID (Direct) */
#define I3C_CCC_GETPID 0x8DU
/** Get Bus Characteristics Register (Direct) */
#define I3C_CCC_GETBCR 0x8EU
/** Get Device Characteristics Register (Direct) */
#define I3C_CCC_GETDCR 0x8FU
/** Get Device Status (Direct) */
#define I3C_CCC_GETSTATUS 0x90U
/** Get Accept Controller Role (Direct) */
#define I3C_CCC_GETACCCR 0x91U
/** Set Bridge Targets (Direct) */
#define I3C_CCC_SETBRGTGT 0x93U
/** Get Max Data Speed (Direct) */
#define I3C_CCC_GETMXDS 0x94U
/** Get Optional Feature Capabilities (Direct) */
#define I3C_CCC_GETCAPS 0x95U
/** Set Route (Direct) */
#define I3C_CCC_SETROUTE 0x96U
/** Device to Device(s) Tunneling Control (Direct) */
#define I3C_CCC_D2DXFER 0x97U
/** Get Exchange Timing Information (Direct) */
#define I3C_CCC_GETXTIME 0x99U
/** Set Group Address (Direct) */
#define I3C_CCC_SETGRPA 0x9BU
struct i3c_device_desc;
/**
* @brief Payload structure for Direct CCC to one target.
*/
struct i3c_ccc_target_payload {
/** Target address */
uint8_t addr;
/** @c 0 for Write, @c 1 for Read */
uint8_t rnw:1;
/**
* - For Write CCC, pointer to the byte array of data
* to be sent, which may contain the Sub-Command Byte
* and additional data.
* - For Read CCC, pointer to the byte buffer for data
* to be read into.
*/
uint8_t *data;
/** Length in bytes for @p data. */
size_t data_len;
};
/**
* @brief Payload structure for one CCC transaction.
*/
struct i3c_ccc_payload {
struct {
/**
* The CCC ID (@c I3C_CCC_*).
*/
uint8_t id;
/**
* Pointer to byte array of data for this CCC.
*
* This is the bytes following the CCC command in CCC frame.
* Set to @c NULL if no associated data.
*/
uint8_t *data;
/** Length in bytes for optional data array. */
size_t data_len;
} ccc;
struct {
/**
* Array of struct i3c_ccc_target_payload.
*
* Each element describes the target and associated
* payloads for this CCC.
*
* Use with Direct CCC.
*/
struct i3c_ccc_target_payload *payloads;
/** Number of targets */
size_t num_targets;
} targets;
};
/**
* @brief Payload for ENEC/DISEC CCC (Target Events Command).
*/
struct i3c_ccc_events {
/**
* Event byte:
* - Bit[0]: ENINT/DISINT:
* - Target Interrupt Requests
* - Bit[1]: ENCR/DISCR:
* - Controller Role Requests
* - Bit[3]: ENHJ/DISHJ:
* - Hot-Join Event
*/
uint8_t events;
} __packed;
/* For Enable Events */
#define I3C_CCC_ENEC_EVT_ENINTR BIT(0)
#define I3C_CCC_ENEC_EVT_ENCR BIT(1)
#define I3C_CCC_ENEC_EVT_ENHJ BIT(3)
#define I3C_CCC_ENEC_EVT_ALL \
(I3C_CCC_ENEC_EVT_ENINTR | I3C_CCC_ENEC_EVT_ENCR | I3C_CCC_ENEC_EVT_ENHJ)
/* For Disable Events */
#define I3C_CCC_DISEC_EVT_DISINTR BIT(0)
#define I3C_CCC_DISEC_EVT_DISCR BIT(1)
#define I3C_CCC_DISEC_EVT_DISHJ BIT(3)
#define I3C_CCC_DISEC_EVT_ALL \
(I3C_CCC_DISEC_EVT_DISINTR | I3C_CCC_DISEC_EVT_DISCR | I3C_CCC_DISEC_EVT_DISHJ)
/*
* Events for both enabling and disabling since
* they have the same bits.
*/
#define I3C_CCC_EVT_INTR BIT(0)
#define I3C_CCC_EVT_CR BIT(1)
#define I3C_CCC_EVT_HJ BIT(3)
#define I3C_CCC_EVT_ALL \
(I3C_CCC_EVT_INTR | I3C_CCC_EVT_CR | I3C_CCC_EVT_HJ)
/**
* @brief Payload for SETMWL/GETMWL CCC (Set/Get Maximum Write Length).
*
* @note For drivers and help functions, the raw data coming
* back from target device is in big endian. This needs to be
* translated back to CPU endianness before passing back to
* function caller.
*/
struct i3c_ccc_mwl {
/** Maximum Write Length */
uint16_t len;
} __packed;
/**
* @brief Payload for SETMRL/GETMRL CCC (Set/Get Maximum Read Length).
*
* @note For drivers and help functions, the raw data coming
* back from target device is in big endian. This needs to be
* translated back to CPU endianness before passing back to
* function caller.
*/
struct i3c_ccc_mrl {
/** Maximum Read Length */
uint16_t len;
/** Optional IBI Payload Size */
uint8_t ibi_len;
} __packed;
/**
* @brief The active controller part of payload for DEFTGTS CCC.
*
* This is used by DEFTGTS (Define List of Targets) CCC to describe
* the active controller on the I3C bus.
*/
struct i3c_ccc_deftgts_active_controller {
/** Dynamic Address of Active Controller */
uint8_t addr;
/** Device Characteristic Register of Active Controller */
uint8_t dcr;
/** Bus Characteristic Register of Active Controller */
uint8_t bcr;
/** Static Address of Active Controller */
uint8_t static_addr;
};
/**
* @brief The target device part of payload for DEFTGTS CCC.
*
* This is used by DEFTGTS (Define List of Targets) CCC to describe
* the existing target devices on the I3C bus.
*/
struct i3c_ccc_deftgts_target {
/** Dynamic Address of a target device, or a group address */
uint8_t addr;
union {
/**
* Device Characteristic Register of a I3C target device
* or a group.
*/
uint8_t dcr;
/** Legacy Virtual Register for legacy I2C device. */
uint8_t lvr;
};
/** Bus Characteristic Register of a target device or a group */
uint8_t bcr;
/** Static Address of a target device or a group */
uint8_t static_addr;
};
/**
* @brief Payload for DEFTGTS CCC (Define List of Targets).
*
* @note @p i3c_ccc_deftgts_target is an array of targets, where
* the number of elements is dependent on the number of I3C targets
* on the bus. Please have enough space for both read and write of
* this CCC.
*/
struct i3c_ccc_deftgts {
/** Data describing the active controller */
struct i3c_ccc_deftgts_active_controller active_controller;
/** Data describing the target(s) on the bus */
struct i3c_ccc_deftgts_target targets[];
} __packed;
/**
* @brief Payload for a single device address.
*
* This is used for:
* - SETDASA (Set Dynamic Address from Static Address)
* - SETNEWDA (Set New Dynamic Address)
* - SETGRPA (Set Group Address)
* - GETACCCR (Get Accept Controller Role)
*
* Note that the target address is encoded within
* struct i3c_ccc_target_payload instead of being encoded in
* this payload.
*/
struct i3c_ccc_address {
/**
* - For SETDASA, Static Address to be assigned as
* Dynamic Address.
* - For SETNEWDA, new Dynamic Address to be assigned.
* - For SETGRPA, new Group Address to be set.
* - For GETACCCR, the correct address of Secondary
* Controller.
*
* @note For SETDATA, SETNEWDA and SETGRAP,
* the address is left-shift by 1, and bit[0] is always 0.
*
* @note Fpr SET GETACCCR, the address is left-shift by 1,
* and bit[0] is the calculated odd parity bit.
*/
uint8_t addr;
} __packed;
/**
* @brief Payload for GETPID CCC (Get Provisioned ID).
*/
struct i3c_ccc_getpid {
/**
* 48-bit Provisioned ID.
*
* @note Data is big-endian where first byte is MSB.
*/
uint8_t pid[6];
} __packed;
/**
* @brief Payload for GETBCR CCC (Get Bus Characteristics Register).
*/
struct i3c_ccc_getbcr {
/** Bus Characteristics Register */
uint8_t bcr;
} __packed;
/**
* @brief Payload for GETDCR CCC (Get Device Characteristics Register).
*/
struct i3c_ccc_getdcr {
/** Device Characteristics Register */
uint8_t dcr;
} __packed;
/**
* @brief Indicate which format of GETSTATUS to use.
*/
enum i3c_ccc_getstatus_fmt {
GETSTATUS_FORMAT_1,
GETSTATUS_FORMAT_2,
};
enum i3c_ccc_getstatus_defbyte {
GETSTATUS_FORMAT_2_TGTSTAT = 0x00U,
GETSTATUS_FORMAT_2_PRECR = 0x91U,
GETSTATUS_FORMAT_2_INVALID = 0x100U
};
/**
* @brief Payload for GETSTATUS CCC (Get Device Status).
*/
union i3c_ccc_getstatus {
struct {
/**
* Device Status
* - Bit[15:8]: Reserved.
* - Bit[7:6]: Activity Mode.
* - Bit[5]: Protocol Error.
* - Bit[4]: Reserved.
* - Bit[3:0]: Number of Pending Interrupts.
*
* @note For drivers and help functions, the raw data coming
* back from target device is in big endian. This needs to be
* translated back to CPU endianness before passing back to
* function caller.
*/
uint16_t status;
} fmt1;
union {
/**
* Defining Byte 0x00: TGTSTAT
*
* @see i3c_ccc_getstatus::fmt1::status
*/
uint16_t tgtstat;
/**
* Defining Byte 0x91: PRECR
* - Bit[15:8]: Vendor Reserved
* - Bit[7:2]: Reserved
* - Bit[1]: Handoff Delay NACK
* - Bit[0]: Deep Sleep Detected
*
* @note For drivers and help functions, the raw data coming
* back from target device is in big endian. This needs to be
* translated back to CPU endianness before passing back to
* function caller.
*/
uint16_t precr;
uint16_t raw_u16;
} fmt2;
} __packed;
#define I3C_CCC_GETSTATUS_PROTOCOL_ERR BIT(5)
#define I3C_CCC_GETSTATUS_ACTIVITY_MODE_SHIFT 6
#define I3C_CCC_GETSTATUS_ACTIVITY_MODE_MASK \
(0x03U << I3C_CCC_GETSTATUS_ACTIVITY_MODE_SHIFT)
#define I3C_CCC_GETSTATUS_ACTIVITY_MODE(status) \
(((status) & I3C_CCC_GETSTATUS_ACTIVITY_MODE_MASK) \
>> I3C_CCC_GETSTATUS_ACTIVITY_MODE_SHIFT)
#define I3C_CCC_GETSTATUS_NUM_INT_SHIFT 0
#define I3C_CCC_GETSTATUS_NUM_INT_MASK \
(0x0FU << I3C_CCC_GETSTATUS_NUM_INT_SHIFT)
#define I3C_CCC_GETSTATUS_NUM_INT(status) \
(((status) & I3C_CCC_GETSTATUS_NUM_INT_MASK) \
>> I3C_CCC_GETSTATUS_NUM_INT_SHIFT)
#define I3C_CCC_GETSTATUS_PRECR_DEEP_SLEEP_DETECTED BIT(0)
#define I3C_CCC_GETSTATUS_PRECR_HANDOFF_DELAY_NACK BIT(1)
/**
* @brief One Bridged Target for SETBRGTGT payload.
*/
struct i3c_ccc_setbrgtgt_tgt {
/**
* Dynamic address of the bridged target.
*
* @note The address is left-shift by 1, and bit[0]
* is always 0.
*/
uint8_t addr;
/**
* 16-bit ID for the bridged target.
*
* @note For drivers and help functions, the raw data coming
* back from target device is in big endian. This needs to be
* translated back to CPU endianness before passing back to
* function caller.
*/
uint16_t id;
} __packed;
/**
* @brief Payload for SETBRGTGT CCC (Set Bridge Targets).
*
* Note that the bridge target address is encoded within
* struct i3c_ccc_target_payload instead of being encoded in
* this payload.
*/
struct i3c_ccc_setbrgtgt {
/** Number of bridged targets */
uint8_t count;
/** Array of bridged targets */
struct i3c_ccc_setbrgtgt_tgt targets[];
} __packed;
/**
* @brief Payload for GETMXDS CCC (Get Max Data Speed).
*
* @note This is only for GETMXDS Format 1 and Format 2.
*/
union i3c_ccc_getmxds {
struct {
/** maxWr */
uint8_t maxwr;
/** maxRd */
uint8_t maxrd;
} fmt1;
struct {
/** maxWr */
uint8_t maxwr;
/** maxRd */
uint8_t maxrd;
/**
* Maximum Read Turnaround Time in microsecond.
*
* This is in little-endian where first byte is LSB.
*/
uint8_t maxrdturn[3];
} fmt2;
struct {
/**
* Defining Byte 0x00: WRRDTURN
*
* @see i3c_ccc_getmxds::fmt2
*/
uint8_t wrrdturn;
/**
* Defining Byte 0x91: CRHDLY
* - Bit[2]: Set Bus Actibity State
* - Bit[1:0]: Controller Handoff Activity State
*/
uint8_t crhdly1;
} fmt3;
} __packed;
#define I3C_CCC_GETMXDS_MAX_SDR_FSCL_MAX 0
#define I3C_CCC_GETMXDS_MAX_SDR_FSCL_8MHZ 1
#define I3C_CCC_GETMXDS_MAX_SDR_FSCL_6MHZ 2
#define I3C_CCC_GETMXDS_MAX_SDR_FSCL_4MHZ 3
#define I3C_CCC_GETMXDS_MAX_SDR_FSCL_2MHZ 4
#define I3C_CCC_GETMXDS_TSCO_8NS 0
#define I3C_CCC_GETMXDS_TSCO_9NS 1
#define I3C_CCC_GETMXDS_TSCO_10NS 2
#define I3C_CCC_GETMXDS_TSCO_11NS 3
#define I3C_CCC_GETMXDS_TSCO_12NS 4
#define I3C_CCC_GETMXDS_TSCO_GT_12NS 7
#define I3C_CCC_GETMXDS_MAXWR_DEFINING_BYTE_SUPPORT BIT(3)
#define I3C_CCC_GETMXDS_MAXWR_MAX_SDR_FSCL_SHIFT 0
#define I3C_CCC_GETMXDS_MAXWR_MAX_SDR_FSCL_MASK \
(0x07U << I3C_CCC_GET_MXDS_MAXWR_MAX_SDR_FSCL_SHIFT)
#define I3C_CCC_GETMXDS_MAXWR_MAX_SDR_FSCL(maxwr) \
(((maxwr) & \
I3C_CCC_GETMXDS_MAXWR_MAX_SDR_FSCL_MASK) \
>> I3C_CCC_GETMXDS_MAXWR_MAX_SDR_FSCL_SHIFT)
#define I3C_CCC_GETMXDS_MAXRD_W2R_PERMITS_STOP_BETWEEN BIT(6)
#define I3C_CCC_GETMXDS_MAXRD_TSCO_SHIFT 3
#define I3C_CCC_GETMXDS_MAXRD_TSCO_MASK \
(0x07U << I3C_CCC_GETMXDS_MAXRD_TSCO_SHIFT)
#define I3C_CCC_GETMXDS_MAXRD_TSCO(maxrd) \
(((maxrd) & I3C_CCC_GETMXDS_MAXRD_TSCO_MASK) \
>> I3C_CCC_GETMXDS_MAXRD_TSCO_SHIFT)
#define I3C_CCC_GETMXDS_MAXRD_MAX_SDR_FSCL_SHIFT 0
#define I3C_CCC_GETMXDS_MAXRD_MAX_SDR_FSCL_MASK \
(0x07U << I3C_CCC_GET_MXDS_MAXRD_MAX_SDR_FSCL_SHIFT)
#define I3C_CCC_GETMXDS_MAXRD_MAX_SDR_FSCL(maxrd) \
(((maxrd) & \
I3C_CCC_GETMXDS_MAXRD_MAX_SDR_FSCL_MASK) \
>> I3C_CCC_GETMXDS_MAXRD_MAX_SDR_FSCL_SHIFT)
#define I3C_CCC_GETMXDS_CRDHLY1_SET_BUS_ACT_STATE BIT(2)
#define I3C_CCC_GETMXDS_CRDHLY1_CTRL_HANDOFF_ACT_STATE_SHIFT 0
#define I3C_CCC_GETMXDS_CRDHLY1_CTRL_HANDOFF_ACT_STATE_MASK \
(0x03U << I3C_CCC_GETMXDS_CRDHLY1_SET_BUS_ACT_STATE_SHIFT)
#define I3C_CCC_GETMXDS_CRDHLY1_CTRL_HANDOFF_ACT_STATE(crhdly1) \
(((crhdly1) & \
I3C_CCC_GETMXDS_CRDHLY1_SET_BUS_ACT_STATE_MASK) \
>> I3C_CCC_GETMXDS_CRDHLY1_SET_BUS_ACT_STATE_SHIFT)
/**
* @brief Payload for GETCAPS CCC (Get Optional Feature Capabilities).
*
* @note Only support GETCAPS Format 1.
*/
struct i3c_ccc_getcaps {
/**
* GETCAP[1-4] bytes.
*/
uint8_t getcaps[4];
} __packed;
#define I3C_CCC_GETCAPS1_HDR_DDR BIT(0)
#define I3C_CCC_GETCAPS1_HDR_BT BIT(3)
#define I3C_CCC_GETCAPS1_HDR_MODE(x) BIT(x)
#define I3C_CCC_GETCAPS1_HDR_MODE0 BIT(0)
#define I3C_CCC_GETCAPS1_HDR_MODE1 BIT(1)
#define I3C_CCC_GETCAPS1_HDR_MODE2 BIT(2)
#define I3C_CCC_GETCAPS1_HDR_MODE3 BIT(3)
#define I3C_CCC_GETCAPS1_HDR_MODE4 BIT(4)
#define I3C_CCC_GETCAPS1_HDR_MODE5 BIT(5)
#define I3C_CCC_GETCAPS1_HDR_MODE6 BIT(6)
#define I3C_CCC_GETCAPS1_HDR_MODE7 BIT(7)
#define I3C_CCC_GETCAPS2_HDRDDR_WRITE_ABORT BIT(6)
#define I3C_CCC_GETCAPS2_HDRDDR_ABORT_CRC BIT(7)
#define I3C_CCC_GETCAPS2_GRPADDR_CAP_SHIFT 4
#define I3C_CCC_GETCAPS2_GRPADDR_CAP_MASK \
(0x03U << I3C_CCC_GETCAPS2_GRPADDR_CAP_SHIFT)
#define I3C_CCC_GETCAPS2_GRPADDR_CAP(getcaps2) \
(((getcaps2) & \
I3C_CCC_GETCAPS2_GRPADDR_CAP_MASK) \
>> I3C_CCC_GETCAPS_GRPADDR_CAP_SHIFT)
#define I3C_CCC_GETCAPS2_SPEC_VER_SHIFT 0
#define I3C_CCC_GETCAPS2_SPEC_VER_MASK \
(0x0FU << I3C_CCC_GETCAPS2_SPEC_VER_SHIFT)
#define I3C_CCC_GETCAPS2_SPEC_VER(getcaps2) \
(((getcaps2) & \
I3C_CCC_GETCAPS2_SPEC_VER_MASK) \
>> I3C_CCC_GETCAPS_SPEC_VER_SHIFT)
#define I3C_CCC_GETCAPS3_MLAME_SUPPORT BIT(0)
#define I3C_CCC_GETCAPS3_D2DXFER_SUPPORT BIT(1)
#define I3C_CCC_GETCAPS3_D3DXFER_IBI_CAPABLE BIT(2)
#define I3C_CCC_GETCAPS3_GETCAPS_DEFINING_BYTE_SUPPORT BIT(3)
#define I3C_CCC_GETCAPS3_GETSTATUS_DEFINING_BYTE_SUPPORT BIT(4)
#define I3C_CCC_GETCAPS3_HDRBT_CRC32_SUPPORT BIT(5)
#define I3C_CCC_GETCAPS3_IBI_MDR_PENDING_READ_NOTIFICATION BIT(6)
enum i3c_ccc_rstact_defining_byte {
I3C_CCC_RSTACT_NO_RESET = 0x00U,
I3C_CCC_RSTACT_PERIPHERAL_ONLY = 0x01U,
I3C_CCC_RSTACT_RESET_WHOLE_TARGET = 0x02U,
I3C_CCC_RSTACT_DEBUG_NETWORK_ADAPTER = 0x03U,
I3C_CCC_RSTACT_VIRTUAL_TARGET_DETECT = 0x04U,
};
/**
* @brief Test if I3C CCC payload is for broadcast.
*
* This tests if the CCC payload is for broadcast.
*
* @param[in] payload Pointer to the CCC payload.
*
* @retval true if payload target is broadcast
* @retval false if payload target is direct
*/
static inline bool i3c_ccc_is_payload_broadcast(const struct i3c_ccc_payload *payload)
{
return (payload->ccc.id <= I3C_CCC_BROADCAST_MAX_ID);
}
/**
* @brief Get BCR from a target
*
* Helper function to get BCR (Bus Characteristic Register) from
* target device.
*
* @param[in] target Pointer to the target device descriptor.
* @param[out] bcr Pointer to the BCR payload structure.
*
* @return @see i3c_do_ccc
*/
int i3c_ccc_do_getbcr(struct i3c_device_desc *target,
struct i3c_ccc_getbcr *bcr);
/**
* @brief Get DCR from a target
*
* Helper function to get DCR (Device Characteristic Register) from
* target device.
*
* @param[in] target Pointer to the target device descriptor.
* @param[out] dcr Pointer to the DCR payload structure.
*
* @return @see i3c_do_ccc
*/
int i3c_ccc_do_getdcr(struct i3c_device_desc *target,
struct i3c_ccc_getdcr *dcr);
/**
* @brief Get PID from a target
*
* Helper function to get PID (Provisioned ID) from
* target device.
*
* @param[in] target Pointer to the target device descriptor.
* @param[out] pid Pointer to the PID payload structure.
*
* @return @see i3c_do_ccc
*/
int i3c_ccc_do_getpid(struct i3c_device_desc *target,
struct i3c_ccc_getpid *pid);
/**
* @brief Broadcast RSTACT to reset I3C Peripheral.
*
* Helper function to broadcast Target Reset Action (RSTACT) to
* all connected targets to Reset the I3C Peripheral Only (0x01).
*
* @param[in] controller Pointer to the controller device driver instance.
* @param[in] action What reset action to perform.
*
* @return @see i3c_do_ccc
*/
int i3c_ccc_do_rstact_all(const struct device *controller,
enum i3c_ccc_rstact_defining_byte action);
/**
* @brief Broadcast RSTDAA to reset dynamic addresses for all targets.
*
* Helper function to reset dynamic addresses of all connected targets.
*
* @param[in] controller Pointer to the controller device driver instance.
*
* @return @see i3c_do_ccc
*/
int i3c_ccc_do_rstdaa_all(const struct device *controller);
/**
* @brief Set Dynamic Address from Static Address for a target
*
* Helper function to do SETDASA (Set Dynamic Address from Static Address)
* for a particular target.
*
* Note this does not update @p target with the new dynamic address.
*
* @param[in] target Pointer to the target device descriptor where
* the device is configured with a static address.
*
* @return @see i3c_do_ccc
*/
int i3c_ccc_do_setdasa(const struct i3c_device_desc *target);
/**
* @brief Broadcast ENEC/DISEC to enable/disable target events.
*
* Helper function to broadcast Target Events Command to enable or
* disable target events (ENEC/DISEC).
*
* @param[in] controller Pointer to the controller device driver instance.
* @param[in] enable ENEC if true, DISEC if false.
* @param[in] events Pointer to the event struct.
*
* @return @see i3c_do_ccc
*/
int i3c_ccc_do_events_all_set(const struct device *controller,
bool enable, struct i3c_ccc_events *events);
/**
* @brief Direct CCC ENEC/DISEC to enable/disable target events.
*
* Helper function to send Target Events Command to enable or
* disable target events (ENEC/DISEC) on a single target.
*
* @param[in] target Pointer to the target device descriptor.
* @param[in] enable ENEC if true, DISEC if false.
* @param[in] events Pointer to the event struct.
*
* @return @see i3c_do_ccc
*/
int i3c_ccc_do_events_set(struct i3c_device_desc *target,
bool enable, struct i3c_ccc_events *events);
/**
* @brief Broadcast SETMWL to Set Maximum Write Length.
*
* Helper function to do SETMWL (Set Maximum Write Length) to
* all connected targets.
*
* @param[in] controller Pointer to the controller device driver instance.
* @param[in] mwl Pointer to SETMWL payload.
*
* @return @see i3c_do_ccc
*/
int i3c_ccc_do_setmwl_all(const struct device *controller,
const struct i3c_ccc_mwl *mwl);
/**
* @brief Single target SETMWL to Set Maximum Write Length.
*
* Helper function to do SETMWL (Set Maximum Write Length) to
* one target.
*
* @param[in] target Pointer to the target device descriptor.
* @param[in] mwl Pointer to SETMWL payload.
*
* @return @see i3c_do_ccc
*/
int i3c_ccc_do_setmwl(const struct i3c_device_desc *target,
const struct i3c_ccc_mwl *mwl);
/**
* @brief Single target GETMWL to Get Maximum Write Length.
*
* Helper function to do GETMWL (Get Maximum Write Length) of
* one target.
*
* @param[in] target Pointer to the target device descriptor.
* @param[out] mwl Pointer to GETMWL payload.
*
* @return @see i3c_do_ccc
*/
int i3c_ccc_do_getmwl(const struct i3c_device_desc *target,
struct i3c_ccc_mwl *mwl);
/**
* @brief Broadcast SETMRL to Set Maximum Read Length.
*
* Helper function to do SETMRL (Set Maximum Read Length) to
* all connected targets.
*
* @param[in] controller Pointer to the controller device driver instance.
* @param[in] mrl Pointer to SETMRL payload.
* @param[in] has_ibi_size True if also sending the optional IBI payload
* size. False if not sending.
*
* @return @see i3c_do_ccc
*/
int i3c_ccc_do_setmrl_all(const struct device *controller,
const struct i3c_ccc_mrl *mrl,
bool has_ibi_size);
/**
* @brief Single target SETMRL to Set Maximum Read Length.
*
* Helper function to do SETMRL (Set Maximum Read Length) to
* one target.
*
* Note this uses the BCR of the target to determine whether
* to send the optional IBI payload size.
*
* @param[in] target Pointer to the target device descriptor.
* @param[in] mrl Pointer to SETMRL payload.
*
* @return @see i3c_do_ccc
*/
int i3c_ccc_do_setmrl(const struct i3c_device_desc *target,
const struct i3c_ccc_mrl *mrl);
/**
* @brief Single target GETMRL to Get Maximum Read Length.
*
* Helper function to do GETMRL (Get Maximum Read Length) of
* one target.
*
* Note this uses the BCR of the target to determine whether
* to send the optional IBI payload size.
*
* @param[in] target Pointer to the target device descriptor.
* @param[out] mrl Pointer to GETMRL payload.
*
* @return @see i3c_do_ccc
*/
int i3c_ccc_do_getmrl(const struct i3c_device_desc *target,
struct i3c_ccc_mrl *mrl);
/**
* @brief Single target GETSTATUS to Get Target Status.
*
* Helper function to do GETSTATUS (Get Target Status) of
* one target.
*
* Note this uses the BCR of the target to determine whether
* to send the optional IBI payload size.
*
* @param[in] target Pointer to the target device descriptor.
* @param[out] status Pointer to GETSTATUS payload.
* @param[in] fmt Which GETSTATUS to use.
* @param[in] defbyte Defining Byte if using format 2.
*
* @return @see i3c_do_ccc
*/
int i3c_ccc_do_getstatus(const struct i3c_device_desc *target,
union i3c_ccc_getstatus *status,
enum i3c_ccc_getstatus_fmt fmt,
enum i3c_ccc_getstatus_defbyte defbyte);
/**
* @brief Single target GETSTATUS to Get Target Status (Format 1).
*
* Helper function to do GETSTATUS (Get Target Status, format 1) of
* one target.
*
* @param[in] target Pointer to the target device descriptor.
* @param[out] status Pointer to GETSTATUS payload.
*
* @return @see i3c_do_ccc
*/
static inline int i3c_ccc_do_getstatus_fmt1(const struct i3c_device_desc *target,
union i3c_ccc_getstatus *status)
{
return i3c_ccc_do_getstatus(target, status,
GETSTATUS_FORMAT_1,
GETSTATUS_FORMAT_2_INVALID);
}
/**
* @brief Single target GETSTATUS to Get Target Status (Format 2).
*
* Helper function to do GETSTATUS (Get Target Status, format 2) of
* one target.
*
* @param[in] target Pointer to the target device descriptor.
* @param[out] status Pointer to GETSTATUS payload.
* @param[in] defbyte Defining Byte for GETSTATUS format 2.
*
* @return @see i3c_do_ccc
*/
static inline int i3c_ccc_do_getstatus_fmt2(const struct i3c_device_desc *target,
union i3c_ccc_getstatus *status,
enum i3c_ccc_getstatus_defbyte defbyte)
{
return i3c_ccc_do_getstatus(target, status,
GETSTATUS_FORMAT_2, defbyte);
}
#ifdef __cplusplus
}
#endif
/**
* @}
*/
#endif /* ZEPHYR_INCLUDE_DRIVERS_I3C_CCC_H_ */