1 /* 2 * Arm SCP/MCP Software 3 * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 8 #ifndef MOD_PSU_H 9 #define MOD_PSU_H 10 11 #include <fwk_id.h> 12 #include <fwk_module_idx.h> 13 #include <fwk_status.h> 14 15 #include <stdbool.h> 16 #include <stdint.h> 17 18 /*! 19 * \ingroup GroupModules 20 * \defgroup GroupPsu Power Supply Unit (PSU) 21 * 22 * \details The `psu` module represents an abstract interface through which 23 * power supply units can be used. It provides functions for manipulating 24 * the voltage as well as enabling/disabling the supply. 25 * 26 * Users of the HAL interact with the individual power supply units through 27 * the [device API](::mod_psu_device_api). This is the primary interface 28 * that this module exposes and implements. 29 * 30 * Separate to this is the [driver API](::mod_psu_driver_api), through 31 * which the HAL will communicate with various driver implementations. 32 * Driver implementations that need it may also utilise the [driver 33 * response API](::mod_psu_driver_response_api), which allows power supply 34 * units to pend requests and respond on-demand. 35 * 36 * \{ 37 */ 38 39 /*! 40 * \brief API indices. 41 */ 42 enum mod_psu_api_idx { 43 /*! 44 * \brief Device API. 45 * 46 * \note This API identifier implements the ::mod_psu_device_api interface. 47 * 48 * \warning Binding to this API must occur through an element of this 49 * module. 50 */ 51 MOD_PSU_API_IDX_DEVICE, 52 53 /*! 54 * \brief Driver response API index. 55 * 56 * \note This API identifier implements the ::mod_psu_driver_response_api 57 * interface. 58 * 59 * \warning Binding to this API must occur through an element of this 60 * module. 61 */ 62 MOD_PSU_API_IDX_DRIVER_RESPONSE, 63 64 /*! 65 * \brief Number of defined APIs. 66 */ 67 MOD_PSU_API_IDX_COUNT 68 }; 69 70 /*! 71 * \brief Event indices. 72 */ 73 enum mod_psu_event_idx { 74 /*! 75 * \brief Response event to a ::mod_psu_device_api::get_enabled call. 76 * 77 * \note This event identifier uses the ::mod_psu_response structure as its 78 * event parameters. The ::mod_psu_response::enabled field is active. 79 */ 80 MOD_PSU_EVENT_IDX_GET_ENABLED, 81 82 /*! 83 * \brief Response event to a ::mod_psu_device_api::set_enabled call. 84 * 85 * \note This event identifier uses the ::mod_psu_response structure as its 86 * event parameters. 87 */ 88 MOD_PSU_EVENT_IDX_SET_ENABLED, 89 90 /*! 91 * \brief Response event to a ::mod_psu_device_api::get_voltage call. 92 * 93 * \note This event identifier uses the ::mod_psu_response structure as its 94 * event parameters. The ::mod_psu_response::voltage field is active. 95 */ 96 MOD_PSU_EVENT_IDX_GET_VOLTAGE, 97 98 /*! 99 * \brief Response event to a ::mod_psu_device_api::set_voltage call. 100 * 101 * \note This event identifier uses the ::mod_psu_response structure as its 102 * event parameters. 103 */ 104 MOD_PSU_EVENT_IDX_SET_VOLTAGE, 105 106 /*! 107 * \brief Number of defined events. 108 */ 109 MOD_PSU_EVENT_IDX_COUNT, 110 }; 111 112 /*! 113 * \brief Device API. 114 * 115 * \details The PSU device API represents the abstract interface used to control 116 * individual power supplies. 117 * 118 * This is the primary interface through which users of the HAL will 119 * interact with individual power supply units. 120 */ 121 struct mod_psu_device_api { 122 /*! 123 * \brief Get whether the device is enabled or not. 124 * 125 * \param[in] device_id Identifier of the device to get the state of. 126 * \param[out] enabled `true` if the device is enabled, otherwise `false`. 127 * 128 * \retval ::FWK_E_HANDLER An error occurred in the device driver. 129 * \retval ::FWK_E_PARAM One or more parameters were invalid. 130 * \retval ::FWK_E_STATE The device cannot currently accept the request. 131 * \retval ::FWK_SUCCESS The operation succeeded. 132 * 133 * \return Status code representing the result of the operation. 134 */ 135 int (*get_enabled)(fwk_id_t device_id, bool *enabled); 136 137 /*! 138 * \brief Enable or disable the device. 139 * 140 * \param[in] device_id Identifier of the device to set the state of. 141 * \param[in] enable `true` to enable the device, or `false` to disable it. 142 * 143 * \retval ::FWK_E_HANDLER An error occurred in the device driver. 144 * \retval ::FWK_E_PARAM One or more parameters were invalid. 145 * \retval ::FWK_E_STATE The device cannot currently accept the request. 146 * \retval ::FWK_SUCCESS The operation succeeded. 147 * 148 * \return Status code representing the result of the operation. 149 */ 150 int (*set_enabled)(fwk_id_t device_id, bool enable); 151 152 /*! 153 * \brief Get the voltage of a device. 154 * 155 * \param[in] device_id Identifier of the device to get the voltage of. 156 * \param[out] voltage Voltage in millivolts (mV). 157 * 158 * \retval ::FWK_E_HANDLER An error occurred in the device driver. 159 * \retval ::FWK_E_PARAM One or more parameters were invalid. 160 * \retval ::FWK_E_STATE The device cannot currently accept the request. 161 * \retval ::FWK_SUCCESS The operation succeeded. 162 * 163 * \return Status code representing the result of the operation. 164 */ 165 int (*get_voltage)(fwk_id_t device_id, uint32_t *voltage); 166 167 /*! 168 * \brief Set the voltage of a device. 169 * 170 * \param[in] device_id Identifier of the device to set the voltage of. 171 * \param[in] voltage New voltage in millivolts (mV). 172 * 173 * \retval ::FWK_E_HANDLER An error occurred in the device driver. 174 * \retval ::FWK_E_PARAM One or more parameters were invalid. 175 * \retval ::FWK_E_STATE The device cannot currently accept the request. 176 * \retval ::FWK_SUCCESS The operation succeeded. 177 * 178 * \return Status code representing the result of the operation. 179 */ 180 int (*set_voltage)(fwk_id_t device_id, uint32_t voltage); 181 }; 182 183 /*! 184 * \brief Device API identifier. 185 * 186 * \note This identifier corresponds to the ::MOD_PSU_API_IDX_DEVICE API index. 187 */ 188 static const fwk_id_t mod_psu_api_id_device = 189 FWK_ID_API_INIT(FWK_MODULE_IDX_PSU, MOD_PSU_API_IDX_DEVICE); 190 191 /*! 192 * \brief Response parameters. 193 * 194 * \details This structure is passed as the parameters to a response event 195 * dispatched by the `psu` module. 196 */ 197 struct mod_psu_response { 198 /*! 199 * \brief Status code representing the result of the operation. 200 */ 201 int status; 202 203 /*! 204 * \brief Response fields. 205 * 206 * \details These fields are used if the module is responding with extra 207 * information. The activated field, if there is one, is based on the 208 * event identifier of the response. 209 */ 210 union { 211 /*! 212 * \brief `true` if the device is enabled, otherwise `false`. 213 * 214 * \warning Used only in response to a ::mod_psu_device_api::get_enabled 215 * call. 216 */ 217 bool enabled; 218 219 /*! 220 * \brief Voltage in millivolts (mV). 221 * 222 * \warning Used only in response to a ::mod_psu_device_api::get_voltage 223 * call. 224 */ 225 uint32_t voltage; 226 }; 227 }; 228 229 /*! 230 * \brief Identifier for a ::mod_psu_device_api::get_enabled call response 231 * event. 232 * 233 * \note This identifier corresponds to the 234 * ::MOD_PSU_EVENT_IDX_GET_ENABLED event index. 235 */ 236 static const fwk_id_t mod_psu_event_id_get_enabled = FWK_ID_EVENT_INIT( 237 FWK_MODULE_IDX_PSU, MOD_PSU_EVENT_IDX_GET_ENABLED); 238 239 /*! 240 * \brief Identifier for a ::mod_psu_device_api::set_enabled call response 241 * event. 242 * 243 * \note This identifier corresponds to the 244 * ::MOD_PSU_EVENT_IDX_SET_ENABLED event index. 245 */ 246 static const fwk_id_t mod_psu_event_id_set_enabled = FWK_ID_EVENT_INIT( 247 FWK_MODULE_IDX_PSU, MOD_PSU_EVENT_IDX_SET_ENABLED); 248 249 /*! 250 * \brief Identifier for a ::mod_psu_device_api::get_voltage call response 251 * event. 252 * 253 * \note This identifier corresponds to the 254 * ::MOD_PSU_EVENT_IDX_GET_VOLTAGE event index. 255 */ 256 static const fwk_id_t mod_psu_event_id_get_voltage = FWK_ID_EVENT_INIT( 257 FWK_MODULE_IDX_PSU, MOD_PSU_EVENT_IDX_GET_VOLTAGE); 258 259 /*! 260 * \brief Identifier for a ::mod_psu_device_api::set_voltage call response 261 * event. 262 * 263 * \note This identifier corresponds to the 264 * ::MOD_PSU_EVENT_IDX_SET_VOLTAGE event index. 265 */ 266 static const fwk_id_t mod_psu_event_id_set_voltage = FWK_ID_EVENT_INIT( 267 FWK_MODULE_IDX_PSU, MOD_PSU_EVENT_IDX_SET_VOLTAGE); 268 269 /*! 270 * \brief Driver API. 271 * 272 * \details The PSU driver API represents the abstract interface that power 273 * supply drivers must implement in order for the PSU module to interact 274 * with them. 275 */ 276 struct mod_psu_driver_api { 277 /*! 278 * \brief Get whether the device is enabled or not. 279 * 280 * \param[in] id Identifier of the device to get the state of. 281 * \param[out] enabled `true` if the device is enabled, or `false` it is 282 * disabled. 283 * 284 * \retval ::FWK_E_HANDLER The operation failed. 285 * \retval ::FWK_PENDING The result of the operation is pending. 286 * \retval ::FWK_SUCCESS The operation succeeded. 287 * 288 * \return Status code representing the result of the operation. 289 */ 290 int (*get_enabled)(fwk_id_t id, bool *enabled); 291 292 /*! 293 * \brief Enable or disable the device. 294 * 295 * \param[in] id Identifier of the device to set the state of. 296 * \param[in] enable `true` to enable the device, or `false` to disable it. 297 * 298 * \retval ::FWK_E_HANDLER The operation failed. 299 * \retval ::FWK_PENDING The result of the operation is pending. 300 * \retval ::FWK_SUCCESS The operation succeeded. 301 * 302 * \return Status code representing the result of the operation. 303 */ 304 int (*set_enabled)(fwk_id_t id, bool enable); 305 306 /*! 307 * \brief Get the voltage of a device. 308 * 309 * \param[in] id Identifier of the device to get the voltage of. 310 * \param[out] voltage Voltage in millivolts (mV). 311 * 312 * \retval ::FWK_E_HANDLER The operation failed. 313 * \retval ::FWK_PENDING The result of the operation is pending. 314 * \retval ::FWK_SUCCESS The operation succeeded. 315 * 316 * \return Status code representing the result of the operation. 317 */ 318 int (*get_voltage)(fwk_id_t id, uint32_t *voltage); 319 320 /*! 321 * \brief Set the voltage of a device. 322 * 323 * \param[in] id Identifier of the device to set the voltage of. 324 * \param[in] voltage New voltage in millivolts (mV). 325 * 326 * \retval ::FWK_E_HANDLER The operation failed. 327 * \retval ::FWK_PENDING The result of the operation is pending. 328 * \retval ::FWK_SUCCESS The operation succeeded. 329 * 330 * \return Status code representing the result of the operation. 331 */ 332 int (*set_voltage)(fwk_id_t id, uint32_t voltage); 333 }; 334 335 /*! 336 * \brief Driver response. 337 * 338 * \details This structure is passed to the `psu` module through the [driver 339 * response API](::mod_psu_driver_response_api::respond). 340 */ 341 struct mod_psu_driver_response { 342 /*! 343 * \brief Status code representing the result of the operation. 344 */ 345 int status; 346 347 /*! 348 * \brief Response fields. 349 * 350 * \details These fields are used if the driver is responding with extra 351 * information. The activated field, if there is one, is based on the 352 * event type of the response. 353 */ 354 union { 355 /*! 356 * \brief `true` if the device is enabled, otherwise `false`. 357 * 358 * \warning Used only in response to a 359 * ::mod_psu_driver_api::get_enabled call. 360 */ 361 bool enabled; 362 363 /*! 364 * \brief Voltage in millivolts (mV). 365 * 366 * \warning Used only in response to a 367 * ::mod_psu_driver_api::get_voltage call. 368 */ 369 uint32_t voltage; 370 }; 371 }; 372 373 /*! 374 * \brief Driver response API. 375 * 376 * \details The driver response API is the API used by drivers to communicate 377 * the result of a previously-pended operation. 378 */ 379 struct mod_psu_driver_response_api { 380 /*! 381 * \brief Respond to a previous driver request. 382 * 383 * \param element_id Identifier of the power supply element which submitted 384 * the request to the driver. 385 * \param response Driver operation response. 386 */ 387 void (*respond)( 388 fwk_id_t element_id, 389 struct mod_psu_driver_response response); 390 }; 391 392 /*! 393 * \brief Driver response API identifier. 394 * 395 * \note This identifier corresponds to the ::MOD_PSU_API_IDX_DRIVER_RESPONSE 396 * API index. 397 */ 398 static const fwk_id_t mod_psu_api_id_driver_response = 399 FWK_ID_API_INIT(FWK_MODULE_IDX_PSU, MOD_PSU_API_IDX_DRIVER_RESPONSE); 400 401 /*! 402 * \brief Device configuration. 403 * 404 * \details This structure describes configuration parameters for power supply 405 * devices, which are represented as elements of the PSU module. 406 */ 407 struct mod_psu_element_cfg { 408 /*! 409 * \brief Driver entity identifier. 410 * 411 * \details This identifies the entity of the driver, which must implement 412 * ::mod_psu_driver_api. 413 */ 414 fwk_id_t driver_id; 415 416 /*! 417 * \brief Driver API identifier. 418 * 419 * \details This identifies the API of the driver, which must implement 420 * ::mod_psu_driver_api. 421 */ 422 fwk_id_t driver_api_id; 423 }; 424 425 /*! 426 * \} 427 */ 428 429 #endif /* MOD_PSU_H */ 430