Boris Brezillon | 3a379bb | 2017-07-19 11:52:29 +0200 | [diff] [blame^] | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | /* |
| 3 | * Copyright (C) 2018 Cadence Design Systems Inc. |
| 4 | * |
| 5 | * Author: Boris Brezillon <boris.brezillon@bootlin.com> |
| 6 | */ |
| 7 | |
| 8 | #ifndef I3C_CCC_H |
| 9 | #define I3C_CCC_H |
| 10 | |
| 11 | #include <linux/bitops.h> |
| 12 | #include <linux/i3c/device.h> |
| 13 | |
| 14 | /* I3C CCC (Common Command Codes) related definitions */ |
| 15 | #define I3C_CCC_DIRECT BIT(7) |
| 16 | |
| 17 | #define I3C_CCC_ID(id, broadcast) \ |
| 18 | ((id) | ((broadcast) ? 0 : I3C_CCC_DIRECT)) |
| 19 | |
| 20 | /* Commands valid in both broadcast and unicast modes */ |
| 21 | #define I3C_CCC_ENEC(broadcast) I3C_CCC_ID(0x0, broadcast) |
| 22 | #define I3C_CCC_DISEC(broadcast) I3C_CCC_ID(0x1, broadcast) |
| 23 | #define I3C_CCC_ENTAS(as, broadcast) I3C_CCC_ID(0x2 + (as), broadcast) |
| 24 | #define I3C_CCC_RSTDAA(broadcast) I3C_CCC_ID(0x6, broadcast) |
| 25 | #define I3C_CCC_SETMWL(broadcast) I3C_CCC_ID(0x9, broadcast) |
| 26 | #define I3C_CCC_SETMRL(broadcast) I3C_CCC_ID(0xa, broadcast) |
| 27 | #define I3C_CCC_SETXTIME(broadcast) ((broadcast) ? 0x28 : 0x98) |
| 28 | #define I3C_CCC_VENDOR(id, broadcast) ((id) + ((broadcast) ? 0x61 : 0xe0)) |
| 29 | |
| 30 | /* Broadcast-only commands */ |
| 31 | #define I3C_CCC_ENTDAA I3C_CCC_ID(0x7, true) |
| 32 | #define I3C_CCC_DEFSLVS I3C_CCC_ID(0x8, true) |
| 33 | #define I3C_CCC_ENTTM I3C_CCC_ID(0xb, true) |
| 34 | #define I3C_CCC_ENTHDR(x) I3C_CCC_ID(0x20 + (x), true) |
| 35 | |
| 36 | /* Unicast-only commands */ |
| 37 | #define I3C_CCC_SETDASA I3C_CCC_ID(0x7, false) |
| 38 | #define I3C_CCC_SETNEWDA I3C_CCC_ID(0x8, false) |
| 39 | #define I3C_CCC_GETMWL I3C_CCC_ID(0xb, false) |
| 40 | #define I3C_CCC_GETMRL I3C_CCC_ID(0xc, false) |
| 41 | #define I3C_CCC_GETPID I3C_CCC_ID(0xd, false) |
| 42 | #define I3C_CCC_GETBCR I3C_CCC_ID(0xe, false) |
| 43 | #define I3C_CCC_GETDCR I3C_CCC_ID(0xf, false) |
| 44 | #define I3C_CCC_GETSTATUS I3C_CCC_ID(0x10, false) |
| 45 | #define I3C_CCC_GETACCMST I3C_CCC_ID(0x11, false) |
| 46 | #define I3C_CCC_SETBRGTGT I3C_CCC_ID(0x13, false) |
| 47 | #define I3C_CCC_GETMXDS I3C_CCC_ID(0x14, false) |
| 48 | #define I3C_CCC_GETHDRCAP I3C_CCC_ID(0x15, false) |
| 49 | #define I3C_CCC_GETXTIME I3C_CCC_ID(0x19, false) |
| 50 | |
| 51 | #define I3C_CCC_EVENT_SIR BIT(0) |
| 52 | #define I3C_CCC_EVENT_MR BIT(1) |
| 53 | #define I3C_CCC_EVENT_HJ BIT(3) |
| 54 | |
| 55 | /** |
| 56 | * struct i3c_ccc_events - payload passed to ENEC/DISEC CCC |
| 57 | * |
| 58 | * @events: bitmask of I3C_CCC_EVENT_xxx events. |
| 59 | * |
| 60 | * Depending on the CCC command, the specific events coming from all devices |
| 61 | * (broadcast version) or a specific device (unicast version) will be |
| 62 | * enabled (ENEC) or disabled (DISEC). |
| 63 | */ |
| 64 | struct i3c_ccc_events { |
| 65 | u8 events; |
| 66 | }; |
| 67 | |
| 68 | /** |
| 69 | * struct i3c_ccc_mwl - payload passed to SETMWL/GETMWL CCC |
| 70 | * |
| 71 | * @len: maximum write length in bytes |
| 72 | * |
| 73 | * The maximum write length is only applicable to SDR private messages or |
| 74 | * extended Write CCCs (like SETXTIME). |
| 75 | */ |
| 76 | struct i3c_ccc_mwl { |
| 77 | __be16 len; |
| 78 | }; |
| 79 | |
| 80 | /** |
| 81 | * struct i3c_ccc_mrl - payload passed to SETMRL/GETMRL CCC |
| 82 | * |
| 83 | * @len: maximum read length in bytes |
| 84 | * @ibi_len: maximum IBI payload length |
| 85 | * |
| 86 | * The maximum read length is only applicable to SDR private messages or |
| 87 | * extended Read CCCs (like GETXTIME). |
| 88 | * The IBI length is only valid if the I3C slave is IBI capable |
| 89 | * (%I3C_BCR_IBI_REQ_CAP is set). |
| 90 | */ |
| 91 | struct i3c_ccc_mrl { |
| 92 | __be16 read_len; |
| 93 | u8 ibi_len; |
| 94 | } __packed; |
| 95 | |
| 96 | /** |
| 97 | * struct i3c_ccc_dev_desc - I3C/I2C device descriptor used for DEFSLVS |
| 98 | * |
| 99 | * @dyn_addr: dynamic address assigned to the I3C slave or 0 if the entry is |
| 100 | * describing an I2C slave. |
| 101 | * @dcr: DCR value (not applicable to entries describing I2C devices) |
| 102 | * @lvr: LVR value (not applicable to entries describing I3C devices) |
| 103 | * @bcr: BCR value or 0 if this entry is describing an I2C slave |
| 104 | * @static_addr: static address or 0 if the device does not have a static |
| 105 | * address |
| 106 | * |
| 107 | * The DEFSLVS command should be passed an array of i3c_ccc_dev_desc |
| 108 | * descriptors (one entry per I3C/I2C dev controlled by the master). |
| 109 | */ |
| 110 | struct i3c_ccc_dev_desc { |
| 111 | u8 dyn_addr; |
| 112 | union { |
| 113 | u8 dcr; |
| 114 | u8 lvr; |
| 115 | }; |
| 116 | u8 bcr; |
| 117 | u8 static_addr; |
| 118 | }; |
| 119 | |
| 120 | /** |
| 121 | * struct i3c_ccc_defslvs - payload passed to DEFSLVS CCC |
| 122 | * |
| 123 | * @count: number of dev descriptors |
| 124 | * @master: descriptor describing the current master |
| 125 | * @slaves: array of descriptors describing slaves controlled by the |
| 126 | * current master |
| 127 | * |
| 128 | * Information passed to the broadcast DEFSLVS to propagate device |
| 129 | * information to all masters currently acting as slaves on the bus. |
| 130 | * This is only meaningful if you have more than one master. |
| 131 | */ |
| 132 | struct i3c_ccc_defslvs { |
| 133 | u8 count; |
| 134 | struct i3c_ccc_dev_desc master; |
| 135 | struct i3c_ccc_dev_desc slaves[0]; |
| 136 | } __packed; |
| 137 | |
| 138 | /** |
| 139 | * enum i3c_ccc_test_mode - enum listing all available test modes |
| 140 | * |
| 141 | * @I3C_CCC_EXIT_TEST_MODE: exit test mode |
| 142 | * @I3C_CCC_VENDOR_TEST_MODE: enter vendor test mode |
| 143 | */ |
| 144 | enum i3c_ccc_test_mode { |
| 145 | I3C_CCC_EXIT_TEST_MODE, |
| 146 | I3C_CCC_VENDOR_TEST_MODE, |
| 147 | }; |
| 148 | |
| 149 | /** |
| 150 | * struct i3c_ccc_enttm - payload passed to ENTTM CCC |
| 151 | * |
| 152 | * @mode: one of the &enum i3c_ccc_test_mode modes |
| 153 | * |
| 154 | * Information passed to the ENTTM CCC to instruct an I3C device to enter a |
| 155 | * specific test mode. |
| 156 | */ |
| 157 | struct i3c_ccc_enttm { |
| 158 | u8 mode; |
| 159 | }; |
| 160 | |
| 161 | /** |
| 162 | * struct i3c_ccc_setda - payload passed to SETNEWDA and SETDASA CCCs |
| 163 | * |
| 164 | * @addr: dynamic address to assign to an I3C device |
| 165 | * |
| 166 | * Information passed to the SETNEWDA and SETDASA CCCs to assign/change the |
| 167 | * dynamic address of an I3C device. |
| 168 | */ |
| 169 | struct i3c_ccc_setda { |
| 170 | u8 addr; |
| 171 | }; |
| 172 | |
| 173 | /** |
| 174 | * struct i3c_ccc_getpid - payload passed to GETPID CCC |
| 175 | * |
| 176 | * @pid: 48 bits PID in big endian |
| 177 | */ |
| 178 | struct i3c_ccc_getpid { |
| 179 | u8 pid[6]; |
| 180 | }; |
| 181 | |
| 182 | /** |
| 183 | * struct i3c_ccc_getbcr - payload passed to GETBCR CCC |
| 184 | * |
| 185 | * @bcr: BCR (Bus Characteristic Register) value |
| 186 | */ |
| 187 | struct i3c_ccc_getbcr { |
| 188 | u8 bcr; |
| 189 | }; |
| 190 | |
| 191 | /** |
| 192 | * struct i3c_ccc_getdcr - payload passed to GETDCR CCC |
| 193 | * |
| 194 | * @dcr: DCR (Device Characteristic Register) value |
| 195 | */ |
| 196 | struct i3c_ccc_getdcr { |
| 197 | u8 dcr; |
| 198 | }; |
| 199 | |
| 200 | #define I3C_CCC_STATUS_PENDING_INT(status) ((status) & GENMASK(3, 0)) |
| 201 | #define I3C_CCC_STATUS_PROTOCOL_ERROR BIT(5) |
| 202 | #define I3C_CCC_STATUS_ACTIVITY_MODE(status) \ |
| 203 | (((status) & GENMASK(7, 6)) >> 6) |
| 204 | |
| 205 | /** |
| 206 | * struct i3c_ccc_getstatus - payload passed to GETSTATUS CCC |
| 207 | * |
| 208 | * @status: status of the I3C slave (see I3C_CCC_STATUS_xxx macros for more |
| 209 | * information). |
| 210 | */ |
| 211 | struct i3c_ccc_getstatus { |
| 212 | __be16 status; |
| 213 | }; |
| 214 | |
| 215 | /** |
| 216 | * struct i3c_ccc_getaccmst - payload passed to GETACCMST CCC |
| 217 | * |
| 218 | * @newmaster: address of the master taking bus ownership |
| 219 | */ |
| 220 | struct i3c_ccc_getaccmst { |
| 221 | u8 newmaster; |
| 222 | }; |
| 223 | |
| 224 | /** |
| 225 | * struct i3c_ccc_bridged_slave_desc - bridged slave descriptor |
| 226 | * |
| 227 | * @addr: dynamic address of the bridged device |
| 228 | * @id: ID of the slave device behind the bridge |
| 229 | */ |
| 230 | struct i3c_ccc_bridged_slave_desc { |
| 231 | u8 addr; |
| 232 | __be16 id; |
| 233 | } __packed; |
| 234 | |
| 235 | /** |
| 236 | * struct i3c_ccc_setbrgtgt - payload passed to SETBRGTGT CCC |
| 237 | * |
| 238 | * @count: number of bridged slaves |
| 239 | * @bslaves: bridged slave descriptors |
| 240 | */ |
| 241 | struct i3c_ccc_setbrgtgt { |
| 242 | u8 count; |
| 243 | struct i3c_ccc_bridged_slave_desc bslaves[0]; |
| 244 | } __packed; |
| 245 | |
| 246 | /** |
| 247 | * enum i3c_sdr_max_data_rate - max data rate values for private SDR transfers |
| 248 | */ |
| 249 | enum i3c_sdr_max_data_rate { |
| 250 | I3C_SDR0_FSCL_MAX, |
| 251 | I3C_SDR1_FSCL_8MHZ, |
| 252 | I3C_SDR2_FSCL_6MHZ, |
| 253 | I3C_SDR3_FSCL_4MHZ, |
| 254 | I3C_SDR4_FSCL_2MHZ, |
| 255 | }; |
| 256 | |
| 257 | /** |
| 258 | * enum i3c_tsco - clock to data turn-around |
| 259 | */ |
| 260 | enum i3c_tsco { |
| 261 | I3C_TSCO_8NS, |
| 262 | I3C_TSCO_9NS, |
| 263 | I3C_TSCO_10NS, |
| 264 | I3C_TSCO_11NS, |
| 265 | I3C_TSCO_12NS, |
| 266 | }; |
| 267 | |
| 268 | #define I3C_CCC_MAX_SDR_FSCL_MASK GENMASK(2, 0) |
| 269 | #define I3C_CCC_MAX_SDR_FSCL(x) ((x) & I3C_CCC_MAX_SDR_FSCL_MASK) |
| 270 | |
| 271 | /** |
| 272 | * struct i3c_ccc_getmxds - payload passed to GETMXDS CCC |
| 273 | * |
| 274 | * @maxwr: write limitations |
| 275 | * @maxrd: read limitations |
| 276 | * @maxrdturn: maximum read turn-around expressed micro-seconds and |
| 277 | * little-endian formatted |
| 278 | */ |
| 279 | struct i3c_ccc_getmxds { |
| 280 | u8 maxwr; |
| 281 | u8 maxrd; |
| 282 | u8 maxrdturn[3]; |
| 283 | } __packed; |
| 284 | |
| 285 | #define I3C_CCC_HDR_MODE(mode) BIT(mode) |
| 286 | |
| 287 | /** |
| 288 | * struct i3c_ccc_gethdrcap - payload passed to GETHDRCAP CCC |
| 289 | * |
| 290 | * @modes: bitmap of supported HDR modes |
| 291 | */ |
| 292 | struct i3c_ccc_gethdrcap { |
| 293 | u8 modes; |
| 294 | } __packed; |
| 295 | |
| 296 | /** |
| 297 | * enum i3c_ccc_setxtime_subcmd - SETXTIME sub-commands |
| 298 | */ |
| 299 | enum i3c_ccc_setxtime_subcmd { |
| 300 | I3C_CCC_SETXTIME_ST = 0x7f, |
| 301 | I3C_CCC_SETXTIME_DT = 0xbf, |
| 302 | I3C_CCC_SETXTIME_ENTER_ASYNC_MODE0 = 0xdf, |
| 303 | I3C_CCC_SETXTIME_ENTER_ASYNC_MODE1 = 0xef, |
| 304 | I3C_CCC_SETXTIME_ENTER_ASYNC_MODE2 = 0xf7, |
| 305 | I3C_CCC_SETXTIME_ENTER_ASYNC_MODE3 = 0xfb, |
| 306 | I3C_CCC_SETXTIME_ASYNC_TRIGGER = 0xfd, |
| 307 | I3C_CCC_SETXTIME_TPH = 0x3f, |
| 308 | I3C_CCC_SETXTIME_TU = 0x9f, |
| 309 | I3C_CCC_SETXTIME_ODR = 0x8f, |
| 310 | }; |
| 311 | |
| 312 | /** |
| 313 | * struct i3c_ccc_setxtime - payload passed to SETXTIME CCC |
| 314 | * |
| 315 | * @subcmd: one of the sub-commands ddefined in &enum i3c_ccc_setxtime_subcmd |
| 316 | * @data: sub-command payload. Amount of data is determined by |
| 317 | * &i3c_ccc_setxtime->subcmd |
| 318 | */ |
| 319 | struct i3c_ccc_setxtime { |
| 320 | u8 subcmd; |
| 321 | u8 data[0]; |
| 322 | } __packed; |
| 323 | |
| 324 | #define I3C_CCC_GETXTIME_SYNC_MODE BIT(0) |
| 325 | #define I3C_CCC_GETXTIME_ASYNC_MODE(x) BIT((x) + 1) |
| 326 | #define I3C_CCC_GETXTIME_OVERFLOW BIT(7) |
| 327 | |
| 328 | /** |
| 329 | * struct i3c_ccc_getxtime - payload retrieved from GETXTIME CCC |
| 330 | * |
| 331 | * @supported_modes: bitmap describing supported XTIME modes |
| 332 | * @state: current status (enabled mode and overflow status) |
| 333 | * @frequency: slave's internal oscillator frequency in 500KHz steps |
| 334 | * @inaccuracy: slave's internal oscillator inaccuracy in 0.1% steps |
| 335 | */ |
| 336 | struct i3c_ccc_getxtime { |
| 337 | u8 supported_modes; |
| 338 | u8 state; |
| 339 | u8 frequency; |
| 340 | u8 inaccuracy; |
| 341 | } __packed; |
| 342 | |
| 343 | /** |
| 344 | * struct i3c_ccc_cmd_payload - CCC payload |
| 345 | * |
| 346 | * @len: payload length |
| 347 | * @data: payload data. This buffer must be DMA-able |
| 348 | */ |
| 349 | struct i3c_ccc_cmd_payload { |
| 350 | u16 len; |
| 351 | void *data; |
| 352 | }; |
| 353 | |
| 354 | /** |
| 355 | * struct i3c_ccc_cmd_dest - CCC command destination |
| 356 | * |
| 357 | * @addr: can be an I3C device address or the broadcast address if this is a |
| 358 | * broadcast CCC |
| 359 | * @payload: payload to be sent to this device or broadcasted |
| 360 | */ |
| 361 | struct i3c_ccc_cmd_dest { |
| 362 | u8 addr; |
| 363 | struct i3c_ccc_cmd_payload payload; |
| 364 | }; |
| 365 | |
| 366 | /** |
| 367 | * struct i3c_ccc_cmd - CCC command |
| 368 | * |
| 369 | * @rnw: true if the CCC should retrieve data from the device. Only valid for |
| 370 | * unicast commands |
| 371 | * @id: CCC command id |
| 372 | * @ndests: number of destinations. Should always be one for broadcast commands |
| 373 | * @dests: array of destinations and associated payload for this CCC. Most of |
| 374 | * the time, only one destination is provided |
| 375 | * @err: I3C error code |
| 376 | */ |
| 377 | struct i3c_ccc_cmd { |
| 378 | u8 rnw; |
| 379 | u8 id; |
| 380 | unsigned int ndests; |
| 381 | struct i3c_ccc_cmd_dest *dests; |
| 382 | enum i3c_error_code err; |
| 383 | }; |
| 384 | |
| 385 | #endif /* I3C_CCC_H */ |