none
  +   ˆl–Ü4ý( ©³( 	Å€fàB¦-ÿÁ„ Ð?_†I|¥�+ÁÀ '8    /* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (C) 2018 Cadence Design Systems Inc.
 *
 * Author: Boris Brezillon <boris.brezillon@bootlin.com>
 */

#ifndef I3C_CCC_H
#define I3C_CCC_H

#include <linux/bitops.h>
#include <linux/i3c/device.h>

/* I3C CCC (Common Command Codes) related definitions */
#define I3C_CCC_DIRECT			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		BIT(0)
#define I3C_CCC_EVENT_MR		BIT(1)
#define I3C_CCC_EVENT_HJ		BIT(3)

/**
 * 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 {
	u8 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 {
	__be16 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).
 */
struct i3c_ccc_mrl {
	__be16 read_len;
	u8 ibi_len;
} __packed;

/**
 * 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 {
	u8 dyn_addr;
	union {
		u8 dcr;
		u8 lvr;
	};
	u8 bcr;
	u8 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 p