1*af26d7d6STamas Ban /* 2*af26d7d6STamas Ban * Copyright (c) 2020-2022, Arm Limited. All rights reserved. 3*af26d7d6STamas Ban * 4*af26d7d6STamas Ban * SPDX-License-Identifier: BSD-3-Clause 5*af26d7d6STamas Ban */ 6*af26d7d6STamas Ban 7*af26d7d6STamas Ban #include <assert.h> 8*af26d7d6STamas Ban #include <stdbool.h> 9*af26d7d6STamas Ban #include <stdint.h> 10*af26d7d6STamas Ban 11*af26d7d6STamas Ban #include "mhu_v2_x.h" 12*af26d7d6STamas Ban 13*af26d7d6STamas Ban #define MHU_V2_X_MAX_CHANNELS 124 14*af26d7d6STamas Ban #define MHU_V2_1_MAX_CHCOMB_INT 4 15*af26d7d6STamas Ban #define ENABLE 0x1 16*af26d7d6STamas Ban #define DISABLE 0x0 17*af26d7d6STamas Ban #define CLEAR_INTR 0x1 18*af26d7d6STamas Ban #define CH_PER_CH_COMB 0x20 19*af26d7d6STamas Ban #define SEND_FRAME(p_mhu) ((struct mhu_v2_x_send_frame_t *)p_mhu) 20*af26d7d6STamas Ban #define RECV_FRAME(p_mhu) ((struct mhu_v2_x_recv_frame_t *)p_mhu) 21*af26d7d6STamas Ban 22*af26d7d6STamas Ban #define MHU_MAJOR_REV_V2 0x1u 23*af26d7d6STamas Ban #define MHU_MINOR_REV_2_0 0x0u 24*af26d7d6STamas Ban #define MHU_MINOR_REV_2_1 0x1u 25*af26d7d6STamas Ban 26*af26d7d6STamas Ban struct mhu_v2_x_send_ch_window_t { 27*af26d7d6STamas Ban /* Offset: 0x00 (R/ ) Channel Status */ 28*af26d7d6STamas Ban volatile uint32_t ch_st; 29*af26d7d6STamas Ban /* Offset: 0x04 (R/ ) Reserved */ 30*af26d7d6STamas Ban volatile uint32_t reserved_0; 31*af26d7d6STamas Ban /* Offset: 0x08 (R/ ) Reserved */ 32*af26d7d6STamas Ban volatile uint32_t reserved_1; 33*af26d7d6STamas Ban /* Offset: 0x0C ( /W) Channel Set */ 34*af26d7d6STamas Ban volatile uint32_t ch_set; 35*af26d7d6STamas Ban /* Offset: 0x10 (R/ ) Channel Interrupt Status (Reserved in 2.0) */ 36*af26d7d6STamas Ban volatile uint32_t ch_int_st; 37*af26d7d6STamas Ban /* Offset: 0x14 ( /W) Channel Interrupt Clear (Reserved in 2.0) */ 38*af26d7d6STamas Ban volatile uint32_t ch_int_clr; 39*af26d7d6STamas Ban /* Offset: 0x18 (R/W) Channel Interrupt Enable (Reserved in 2.0) */ 40*af26d7d6STamas Ban volatile uint32_t ch_int_en; 41*af26d7d6STamas Ban /* Offset: 0x1C (R/ ) Reserved */ 42*af26d7d6STamas Ban volatile uint32_t reserved_2; 43*af26d7d6STamas Ban }; 44*af26d7d6STamas Ban 45*af26d7d6STamas Ban struct mhu_v2_x_send_frame_t { 46*af26d7d6STamas Ban /* Offset: 0x000 ( / ) Sender Channel Window 0 -123 */ 47*af26d7d6STamas Ban struct mhu_v2_x_send_ch_window_t send_ch_window[MHU_V2_X_MAX_CHANNELS]; 48*af26d7d6STamas Ban /* Offset: 0xF80 (R/ ) Message Handling Unit Configuration */ 49*af26d7d6STamas Ban volatile uint32_t mhu_cfg; 50*af26d7d6STamas Ban /* Offset: 0xF84 (R/W) Response Configuration */ 51*af26d7d6STamas Ban volatile uint32_t resp_cfg; 52*af26d7d6STamas Ban /* Offset: 0xF88 (R/W) Access Request */ 53*af26d7d6STamas Ban volatile uint32_t access_request; 54*af26d7d6STamas Ban /* Offset: 0xF8C (R/ ) Access Ready */ 55*af26d7d6STamas Ban volatile uint32_t access_ready; 56*af26d7d6STamas Ban /* Offset: 0xF90 (R/ ) Interrupt Status */ 57*af26d7d6STamas Ban volatile uint32_t int_st; 58*af26d7d6STamas Ban /* Offset: 0xF94 ( /W) Interrupt Clear */ 59*af26d7d6STamas Ban volatile uint32_t int_clr; 60*af26d7d6STamas Ban /* Offset: 0xF98 (R/W) Interrupt Enable */ 61*af26d7d6STamas Ban volatile uint32_t int_en; 62*af26d7d6STamas Ban /* Offset: 0xF9C (R/ ) Reserved */ 63*af26d7d6STamas Ban volatile uint32_t reserved_0; 64*af26d7d6STamas Ban /* Offset: 0xFA0 (R/W) Channel Combined IRQ Stat (Reserved in 2.0) */ 65*af26d7d6STamas Ban volatile uint32_t ch_comb_int_st[MHU_V2_1_MAX_CHCOMB_INT]; 66*af26d7d6STamas Ban /* Offset: 0xFC4 (R/ ) Reserved */ 67*af26d7d6STamas Ban volatile uint32_t reserved_1[6]; 68*af26d7d6STamas Ban /* Offset: 0xFC8 (R/ ) Implementer Identification Register */ 69*af26d7d6STamas Ban volatile uint32_t iidr; 70*af26d7d6STamas Ban /* Offset: 0xFCC (R/ ) Architecture Identification Register */ 71*af26d7d6STamas Ban volatile uint32_t aidr; 72*af26d7d6STamas Ban /* Offset: 0xFD0 (R/ ) */ 73*af26d7d6STamas Ban volatile uint32_t pid_1[4]; 74*af26d7d6STamas Ban /* Offset: 0xFE0 (R/ ) */ 75*af26d7d6STamas Ban volatile uint32_t pid_0[4]; 76*af26d7d6STamas Ban /* Offset: 0xFF0 (R/ ) */ 77*af26d7d6STamas Ban volatile uint32_t cid[4]; 78*af26d7d6STamas Ban }; 79*af26d7d6STamas Ban 80*af26d7d6STamas Ban struct mhu_v2_x_rec_ch_window_t { 81*af26d7d6STamas Ban /* Offset: 0x00 (R/ ) Channel Status */ 82*af26d7d6STamas Ban volatile uint32_t ch_st; 83*af26d7d6STamas Ban /* Offset: 0x04 (R/ ) Channel Status Masked */ 84*af26d7d6STamas Ban volatile uint32_t ch_st_msk; 85*af26d7d6STamas Ban /* Offset: 0x08 ( /W) Channel Clear */ 86*af26d7d6STamas Ban volatile uint32_t ch_clr; 87*af26d7d6STamas Ban /* Offset: 0x0C (R/ ) Reserved */ 88*af26d7d6STamas Ban volatile uint32_t reserved_0; 89*af26d7d6STamas Ban /* Offset: 0x10 (R/ ) Channel Mask Status */ 90*af26d7d6STamas Ban volatile uint32_t ch_msk_st; 91*af26d7d6STamas Ban /* Offset: 0x14 ( /W) Channel Mask Set */ 92*af26d7d6STamas Ban volatile uint32_t ch_msk_set; 93*af26d7d6STamas Ban /* Offset: 0x18 ( /W) Channel Mask Clear */ 94*af26d7d6STamas Ban volatile uint32_t ch_msk_clr; 95*af26d7d6STamas Ban /* Offset: 0x1C (R/ ) Reserved */ 96*af26d7d6STamas Ban volatile uint32_t reserved_1; 97*af26d7d6STamas Ban }; 98*af26d7d6STamas Ban 99*af26d7d6STamas Ban struct mhu_v2_x_recv_frame_t { 100*af26d7d6STamas Ban /* Offset: 0x000 ( / ) Receiver Channel Window 0 -123 */ 101*af26d7d6STamas Ban struct mhu_v2_x_rec_ch_window_t rec_ch_window[MHU_V2_X_MAX_CHANNELS]; 102*af26d7d6STamas Ban /* Offset: 0xF80 (R/ ) Message Handling Unit Configuration */ 103*af26d7d6STamas Ban volatile uint32_t mhu_cfg; 104*af26d7d6STamas Ban /* Offset: 0xF84 (R/ ) Reserved */ 105*af26d7d6STamas Ban volatile uint32_t reserved_0[3]; 106*af26d7d6STamas Ban /* Offset: 0xF90 (R/ ) Interrupt Status (Reserved in 2.0) */ 107*af26d7d6STamas Ban volatile uint32_t int_st; 108*af26d7d6STamas Ban /* Offset: 0xF94 (R/ ) Interrupt Clear (Reserved in 2.0) */ 109*af26d7d6STamas Ban volatile uint32_t int_clr; 110*af26d7d6STamas Ban /* Offset: 0xF98 (R/W) Interrupt Enable (Reserved in 2.0) */ 111*af26d7d6STamas Ban volatile uint32_t int_en; 112*af26d7d6STamas Ban /* Offset: 0xF9C (R/ ) Reserved */ 113*af26d7d6STamas Ban volatile uint32_t reserved_1; 114*af26d7d6STamas Ban /* Offset: 0xFA0 (R/ ) Channel Combined IRQ Stat (Reserved in 2.0) */ 115*af26d7d6STamas Ban volatile uint32_t ch_comb_int_st[MHU_V2_1_MAX_CHCOMB_INT]; 116*af26d7d6STamas Ban /* Offset: 0xFB0 (R/ ) Reserved */ 117*af26d7d6STamas Ban volatile uint32_t reserved_2[6]; 118*af26d7d6STamas Ban /* Offset: 0xFC8 (R/ ) Implementer Identification Register */ 119*af26d7d6STamas Ban volatile uint32_t iidr; 120*af26d7d6STamas Ban /* Offset: 0xFCC (R/ ) Architecture Identification Register */ 121*af26d7d6STamas Ban volatile uint32_t aidr; 122*af26d7d6STamas Ban /* Offset: 0xFD0 (R/ ) */ 123*af26d7d6STamas Ban volatile uint32_t pid_1[4]; 124*af26d7d6STamas Ban /* Offset: 0xFE0 (R/ ) */ 125*af26d7d6STamas Ban volatile uint32_t pid_0[4]; 126*af26d7d6STamas Ban /* Offset: 0xFF0 (R/ ) */ 127*af26d7d6STamas Ban volatile uint32_t cid[4]; 128*af26d7d6STamas Ban }; 129*af26d7d6STamas Ban 130*af26d7d6STamas Ban union mhu_v2_x_frame { 131*af26d7d6STamas Ban struct mhu_v2_x_send_frame_t send_frame; 132*af26d7d6STamas Ban struct mhu_v2_x_recv_frame_t recv_frame; 133*af26d7d6STamas Ban }; 134*af26d7d6STamas Ban 135*af26d7d6STamas Ban enum mhu_v2_x_error_t mhu_v2_x_driver_init(struct mhu_v2_x_dev_t *dev, 136*af26d7d6STamas Ban enum mhu_v2_x_supported_revisions rev) 137*af26d7d6STamas Ban { 138*af26d7d6STamas Ban uint32_t AIDR = 0; 139*af26d7d6STamas Ban union mhu_v2_x_frame *p_mhu; 140*af26d7d6STamas Ban 141*af26d7d6STamas Ban assert(dev != NULL); 142*af26d7d6STamas Ban 143*af26d7d6STamas Ban p_mhu = (union mhu_v2_x_frame *)dev->base; 144*af26d7d6STamas Ban 145*af26d7d6STamas Ban if (dev->is_initialized) { 146*af26d7d6STamas Ban return MHU_V_2_X_ERR_ALREADY_INIT; 147*af26d7d6STamas Ban } 148*af26d7d6STamas Ban 149*af26d7d6STamas Ban if (rev == MHU_REV_READ_FROM_HW) { 150*af26d7d6STamas Ban /* Read revision from HW */ 151*af26d7d6STamas Ban if (dev->frame == MHU_V2_X_RECEIVER_FRAME) { 152*af26d7d6STamas Ban AIDR = p_mhu->recv_frame.aidr; 153*af26d7d6STamas Ban } else { 154*af26d7d6STamas Ban AIDR = p_mhu->send_frame.aidr; 155*af26d7d6STamas Ban } 156*af26d7d6STamas Ban 157*af26d7d6STamas Ban /* Get bits 7:4 to read major revision */ 158*af26d7d6STamas Ban if (((AIDR >> 4) & 0b1111) != MHU_MAJOR_REV_V2) { 159*af26d7d6STamas Ban /* Unsupported MHU version */ 160*af26d7d6STamas Ban return MHU_V_2_X_ERR_UNSUPPORTED_VERSION; 161*af26d7d6STamas Ban } /* No need to save major version, driver only supports MHUv2 */ 162*af26d7d6STamas Ban 163*af26d7d6STamas Ban /* Get bits 3:0 to read minor revision */ 164*af26d7d6STamas Ban dev->subversion = AIDR & 0b1111; 165*af26d7d6STamas Ban 166*af26d7d6STamas Ban if (dev->subversion != MHU_MINOR_REV_2_0 && 167*af26d7d6STamas Ban dev->subversion != MHU_MINOR_REV_2_1) { 168*af26d7d6STamas Ban /* Unsupported subversion */ 169*af26d7d6STamas Ban return MHU_V_2_X_ERR_UNSUPPORTED_VERSION; 170*af26d7d6STamas Ban } 171*af26d7d6STamas Ban } else { 172*af26d7d6STamas Ban /* Revisions were provided by caller */ 173*af26d7d6STamas Ban if (rev == MHU_REV_2_0) { 174*af26d7d6STamas Ban dev->subversion = MHU_MINOR_REV_2_0; 175*af26d7d6STamas Ban } else if (rev == MHU_REV_2_1) { 176*af26d7d6STamas Ban dev->subversion = MHU_MINOR_REV_2_1; 177*af26d7d6STamas Ban } else { 178*af26d7d6STamas Ban /* Unsupported subversion */ 179*af26d7d6STamas Ban return MHU_V_2_X_ERR_UNSUPPORTED_VERSION; 180*af26d7d6STamas Ban } /* No need to save major version, driver only supports MHUv2 */ 181*af26d7d6STamas Ban } 182*af26d7d6STamas Ban 183*af26d7d6STamas Ban dev->is_initialized = true; 184*af26d7d6STamas Ban 185*af26d7d6STamas Ban return MHU_V_2_X_ERR_NONE; 186*af26d7d6STamas Ban } 187*af26d7d6STamas Ban 188*af26d7d6STamas Ban uint32_t mhu_v2_x_get_num_channel_implemented(const struct mhu_v2_x_dev_t *dev) 189*af26d7d6STamas Ban { 190*af26d7d6STamas Ban union mhu_v2_x_frame *p_mhu; 191*af26d7d6STamas Ban 192*af26d7d6STamas Ban assert(dev != NULL); 193*af26d7d6STamas Ban 194*af26d7d6STamas Ban p_mhu = (union mhu_v2_x_frame *)dev->base; 195*af26d7d6STamas Ban 196*af26d7d6STamas Ban if (!(dev->is_initialized)) { 197*af26d7d6STamas Ban return MHU_V_2_X_ERR_NOT_INIT; 198*af26d7d6STamas Ban } 199*af26d7d6STamas Ban 200*af26d7d6STamas Ban if (dev->frame == MHU_V2_X_SENDER_FRAME) { 201*af26d7d6STamas Ban return (SEND_FRAME(p_mhu))->mhu_cfg; 202*af26d7d6STamas Ban } else { 203*af26d7d6STamas Ban assert(dev->frame == MHU_V2_X_RECEIVER_FRAME); 204*af26d7d6STamas Ban return (RECV_FRAME(p_mhu))->mhu_cfg; 205*af26d7d6STamas Ban } 206*af26d7d6STamas Ban } 207*af26d7d6STamas Ban 208*af26d7d6STamas Ban enum mhu_v2_x_error_t mhu_v2_x_channel_send(const struct mhu_v2_x_dev_t *dev, 209*af26d7d6STamas Ban uint32_t channel, uint32_t val) 210*af26d7d6STamas Ban { 211*af26d7d6STamas Ban union mhu_v2_x_frame *p_mhu; 212*af26d7d6STamas Ban 213*af26d7d6STamas Ban assert(dev != NULL); 214*af26d7d6STamas Ban 215*af26d7d6STamas Ban p_mhu = (union mhu_v2_x_frame *)dev->base; 216*af26d7d6STamas Ban 217*af26d7d6STamas Ban if (!(dev->is_initialized)) { 218*af26d7d6STamas Ban return MHU_V_2_X_ERR_NOT_INIT; 219*af26d7d6STamas Ban } 220*af26d7d6STamas Ban 221*af26d7d6STamas Ban if (dev->frame == MHU_V2_X_SENDER_FRAME) { 222*af26d7d6STamas Ban (SEND_FRAME(p_mhu))->send_ch_window[channel].ch_set = val; 223*af26d7d6STamas Ban return MHU_V_2_X_ERR_NONE; 224*af26d7d6STamas Ban } else { 225*af26d7d6STamas Ban return MHU_V_2_X_ERR_INVALID_ARG; 226*af26d7d6STamas Ban } 227*af26d7d6STamas Ban } 228*af26d7d6STamas Ban 229*af26d7d6STamas Ban enum mhu_v2_x_error_t mhu_v2_x_channel_poll(const struct mhu_v2_x_dev_t *dev, 230*af26d7d6STamas Ban uint32_t channel, uint32_t *value) 231*af26d7d6STamas Ban { 232*af26d7d6STamas Ban union mhu_v2_x_frame *p_mhu; 233*af26d7d6STamas Ban 234*af26d7d6STamas Ban assert(dev != NULL); 235*af26d7d6STamas Ban 236*af26d7d6STamas Ban p_mhu = (union mhu_v2_x_frame *)dev->base; 237*af26d7d6STamas Ban 238*af26d7d6STamas Ban if (!(dev->is_initialized)) { 239*af26d7d6STamas Ban return MHU_V_2_X_ERR_NOT_INIT; 240*af26d7d6STamas Ban } 241*af26d7d6STamas Ban 242*af26d7d6STamas Ban if (dev->frame == MHU_V2_X_SENDER_FRAME) { 243*af26d7d6STamas Ban *value = (SEND_FRAME(p_mhu))->send_ch_window[channel].ch_st; 244*af26d7d6STamas Ban return MHU_V_2_X_ERR_NONE; 245*af26d7d6STamas Ban } else { 246*af26d7d6STamas Ban return MHU_V_2_X_ERR_INVALID_ARG; 247*af26d7d6STamas Ban } 248*af26d7d6STamas Ban } 249*af26d7d6STamas Ban 250*af26d7d6STamas Ban enum mhu_v2_x_error_t mhu_v2_x_channel_clear(const struct mhu_v2_x_dev_t *dev, 251*af26d7d6STamas Ban uint32_t channel) 252*af26d7d6STamas Ban { 253*af26d7d6STamas Ban union mhu_v2_x_frame *p_mhu; 254*af26d7d6STamas Ban 255*af26d7d6STamas Ban assert(dev != NULL); 256*af26d7d6STamas Ban 257*af26d7d6STamas Ban p_mhu = (union mhu_v2_x_frame *)dev->base; 258*af26d7d6STamas Ban 259*af26d7d6STamas Ban if (!(dev->is_initialized)) { 260*af26d7d6STamas Ban return MHU_V_2_X_ERR_NOT_INIT; 261*af26d7d6STamas Ban } 262*af26d7d6STamas Ban 263*af26d7d6STamas Ban if (dev->frame == MHU_V2_X_RECEIVER_FRAME) { 264*af26d7d6STamas Ban (RECV_FRAME(p_mhu))->rec_ch_window[channel].ch_clr = UINT32_MAX; 265*af26d7d6STamas Ban return MHU_V_2_X_ERR_NONE; 266*af26d7d6STamas Ban } else { 267*af26d7d6STamas Ban return MHU_V_2_X_ERR_INVALID_ARG; 268*af26d7d6STamas Ban } 269*af26d7d6STamas Ban } 270*af26d7d6STamas Ban 271*af26d7d6STamas Ban enum mhu_v2_x_error_t mhu_v2_x_channel_receive( 272*af26d7d6STamas Ban const struct mhu_v2_x_dev_t *dev, uint32_t channel, uint32_t *value) 273*af26d7d6STamas Ban { 274*af26d7d6STamas Ban union mhu_v2_x_frame *p_mhu; 275*af26d7d6STamas Ban 276*af26d7d6STamas Ban assert(dev != NULL); 277*af26d7d6STamas Ban 278*af26d7d6STamas Ban p_mhu = (union mhu_v2_x_frame *)dev->base; 279*af26d7d6STamas Ban 280*af26d7d6STamas Ban if (!(dev->is_initialized)) { 281*af26d7d6STamas Ban return MHU_V_2_X_ERR_NOT_INIT; 282*af26d7d6STamas Ban } 283*af26d7d6STamas Ban 284*af26d7d6STamas Ban if (dev->frame == MHU_V2_X_RECEIVER_FRAME) { 285*af26d7d6STamas Ban *value = (RECV_FRAME(p_mhu))->rec_ch_window[channel].ch_st; 286*af26d7d6STamas Ban return MHU_V_2_X_ERR_NONE; 287*af26d7d6STamas Ban } else { 288*af26d7d6STamas Ban return MHU_V_2_X_ERR_INVALID_ARG; 289*af26d7d6STamas Ban } 290*af26d7d6STamas Ban } 291*af26d7d6STamas Ban 292*af26d7d6STamas Ban enum mhu_v2_x_error_t mhu_v2_x_channel_mask_set( 293*af26d7d6STamas Ban const struct mhu_v2_x_dev_t *dev, uint32_t channel, uint32_t mask) 294*af26d7d6STamas Ban { 295*af26d7d6STamas Ban union mhu_v2_x_frame *p_mhu; 296*af26d7d6STamas Ban 297*af26d7d6STamas Ban assert(dev != NULL); 298*af26d7d6STamas Ban 299*af26d7d6STamas Ban p_mhu = (union mhu_v2_x_frame *)dev->base; 300*af26d7d6STamas Ban 301*af26d7d6STamas Ban if (!(dev->is_initialized)) { 302*af26d7d6STamas Ban return MHU_V_2_X_ERR_NOT_INIT; 303*af26d7d6STamas Ban } 304*af26d7d6STamas Ban 305*af26d7d6STamas Ban if (dev->frame == MHU_V2_X_RECEIVER_FRAME) { 306*af26d7d6STamas Ban (RECV_FRAME(p_mhu))->rec_ch_window[channel].ch_msk_set = mask; 307*af26d7d6STamas Ban return MHU_V_2_X_ERR_NONE; 308*af26d7d6STamas Ban } else { 309*af26d7d6STamas Ban return MHU_V_2_X_ERR_INVALID_ARG; 310*af26d7d6STamas Ban } 311*af26d7d6STamas Ban } 312*af26d7d6STamas Ban 313*af26d7d6STamas Ban enum mhu_v2_x_error_t mhu_v2_x_channel_mask_clear( 314*af26d7d6STamas Ban const struct mhu_v2_x_dev_t *dev, uint32_t channel, uint32_t mask) 315*af26d7d6STamas Ban { 316*af26d7d6STamas Ban union mhu_v2_x_frame *p_mhu; 317*af26d7d6STamas Ban 318*af26d7d6STamas Ban assert(dev != NULL); 319*af26d7d6STamas Ban 320*af26d7d6STamas Ban p_mhu = (union mhu_v2_x_frame *)dev->base; 321*af26d7d6STamas Ban 322*af26d7d6STamas Ban if (!(dev->is_initialized)) { 323*af26d7d6STamas Ban return MHU_V_2_X_ERR_NOT_INIT; 324*af26d7d6STamas Ban } 325*af26d7d6STamas Ban 326*af26d7d6STamas Ban if (dev->frame == MHU_V2_X_RECEIVER_FRAME) { 327*af26d7d6STamas Ban (RECV_FRAME(p_mhu))->rec_ch_window[channel].ch_msk_clr = mask; 328*af26d7d6STamas Ban return MHU_V_2_X_ERR_NONE; 329*af26d7d6STamas Ban } else { 330*af26d7d6STamas Ban return MHU_V_2_X_ERR_INVALID_ARG; 331*af26d7d6STamas Ban } 332*af26d7d6STamas Ban } 333*af26d7d6STamas Ban enum mhu_v2_x_error_t mhu_v2_x_initiate_transfer( 334*af26d7d6STamas Ban const struct mhu_v2_x_dev_t *dev) 335*af26d7d6STamas Ban { 336*af26d7d6STamas Ban union mhu_v2_x_frame *p_mhu; 337*af26d7d6STamas Ban 338*af26d7d6STamas Ban assert(dev != NULL); 339*af26d7d6STamas Ban 340*af26d7d6STamas Ban p_mhu = (union mhu_v2_x_frame *)dev->base; 341*af26d7d6STamas Ban 342*af26d7d6STamas Ban if (!(dev->is_initialized)) { 343*af26d7d6STamas Ban return MHU_V_2_X_ERR_NOT_INIT; 344*af26d7d6STamas Ban } 345*af26d7d6STamas Ban 346*af26d7d6STamas Ban if (dev->frame != MHU_V2_X_SENDER_FRAME) { 347*af26d7d6STamas Ban return MHU_V_2_X_ERR_INVALID_ARG; 348*af26d7d6STamas Ban } 349*af26d7d6STamas Ban 350*af26d7d6STamas Ban (SEND_FRAME(p_mhu))->access_request = ENABLE; 351*af26d7d6STamas Ban 352*af26d7d6STamas Ban while (!((SEND_FRAME(p_mhu))->access_ready)) { 353*af26d7d6STamas Ban /* Wait in a loop for access ready signal to be high */ 354*af26d7d6STamas Ban ; 355*af26d7d6STamas Ban } 356*af26d7d6STamas Ban 357*af26d7d6STamas Ban return MHU_V_2_X_ERR_NONE; 358*af26d7d6STamas Ban } 359*af26d7d6STamas Ban 360*af26d7d6STamas Ban enum mhu_v2_x_error_t mhu_v2_x_close_transfer(const struct mhu_v2_x_dev_t *dev) 361*af26d7d6STamas Ban { 362*af26d7d6STamas Ban union mhu_v2_x_frame *p_mhu; 363*af26d7d6STamas Ban 364*af26d7d6STamas Ban assert(dev != NULL); 365*af26d7d6STamas Ban 366*af26d7d6STamas Ban p_mhu = (union mhu_v2_x_frame *)dev->base; 367*af26d7d6STamas Ban 368*af26d7d6STamas Ban if (!(dev->is_initialized)) { 369*af26d7d6STamas Ban return MHU_V_2_X_ERR_NOT_INIT; 370*af26d7d6STamas Ban } 371*af26d7d6STamas Ban 372*af26d7d6STamas Ban if (dev->frame != MHU_V2_X_SENDER_FRAME) { 373*af26d7d6STamas Ban return MHU_V_2_X_ERR_INVALID_ARG; 374*af26d7d6STamas Ban } 375*af26d7d6STamas Ban 376*af26d7d6STamas Ban (SEND_FRAME(p_mhu))->access_request = DISABLE; 377*af26d7d6STamas Ban 378*af26d7d6STamas Ban return MHU_V_2_X_ERR_NONE; 379*af26d7d6STamas Ban } 380