18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/****************************************************************************** 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci AudioScience HPI driver 58c2ecf20Sopenharmony_ci Copyright (C) 1997-2014 AudioScience Inc. <support@audioscience.com> 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci Hardware Programming Interface (HPI) Utility functions. 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci (C) Copyright AudioScience Inc. 2007 118c2ecf20Sopenharmony_ci*******************************************************************************/ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include "hpi_internal.h" 148c2ecf20Sopenharmony_ci#include "hpimsginit.h" 158c2ecf20Sopenharmony_ci#include <linux/nospec.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci/* The actual message size for each object type */ 188c2ecf20Sopenharmony_cistatic u16 msg_size[HPI_OBJ_MAXINDEX + 1] = HPI_MESSAGE_SIZE_BY_OBJECT; 198c2ecf20Sopenharmony_ci/* The actual response size for each object type */ 208c2ecf20Sopenharmony_cistatic u16 res_size[HPI_OBJ_MAXINDEX + 1] = HPI_RESPONSE_SIZE_BY_OBJECT; 218c2ecf20Sopenharmony_ci/* Flag to enable alternate message type for SSX2 bypass. */ 228c2ecf20Sopenharmony_cistatic u16 gwSSX2_bypass; 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci/** \internal 258c2ecf20Sopenharmony_ci * initialize the HPI message structure 268c2ecf20Sopenharmony_ci */ 278c2ecf20Sopenharmony_cistatic void hpi_init_message(struct hpi_message *phm, u16 object, 288c2ecf20Sopenharmony_ci u16 function) 298c2ecf20Sopenharmony_ci{ 308c2ecf20Sopenharmony_ci u16 size; 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) { 338c2ecf20Sopenharmony_ci object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1); 348c2ecf20Sopenharmony_ci size = msg_size[object]; 358c2ecf20Sopenharmony_ci } else { 368c2ecf20Sopenharmony_ci size = sizeof(*phm); 378c2ecf20Sopenharmony_ci } 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci memset(phm, 0, size); 408c2ecf20Sopenharmony_ci phm->size = size; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci if (gwSSX2_bypass) 438c2ecf20Sopenharmony_ci phm->type = HPI_TYPE_SSX2BYPASS_MESSAGE; 448c2ecf20Sopenharmony_ci else 458c2ecf20Sopenharmony_ci phm->type = HPI_TYPE_REQUEST; 468c2ecf20Sopenharmony_ci phm->object = object; 478c2ecf20Sopenharmony_ci phm->function = function; 488c2ecf20Sopenharmony_ci phm->version = 0; 498c2ecf20Sopenharmony_ci phm->adapter_index = HPI_ADAPTER_INDEX_INVALID; 508c2ecf20Sopenharmony_ci /* Expect actual adapter index to be set by caller */ 518c2ecf20Sopenharmony_ci} 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci/** \internal 548c2ecf20Sopenharmony_ci * initialize the HPI response structure 558c2ecf20Sopenharmony_ci */ 568c2ecf20Sopenharmony_civoid hpi_init_response(struct hpi_response *phr, u16 object, u16 function, 578c2ecf20Sopenharmony_ci u16 error) 588c2ecf20Sopenharmony_ci{ 598c2ecf20Sopenharmony_ci u16 size; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) { 628c2ecf20Sopenharmony_ci object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1); 638c2ecf20Sopenharmony_ci size = res_size[object]; 648c2ecf20Sopenharmony_ci } else { 658c2ecf20Sopenharmony_ci size = sizeof(*phr); 668c2ecf20Sopenharmony_ci } 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci memset(phr, 0, sizeof(*phr)); 698c2ecf20Sopenharmony_ci phr->size = size; 708c2ecf20Sopenharmony_ci phr->type = HPI_TYPE_RESPONSE; 718c2ecf20Sopenharmony_ci phr->object = object; 728c2ecf20Sopenharmony_ci phr->function = function; 738c2ecf20Sopenharmony_ci phr->error = error; 748c2ecf20Sopenharmony_ci phr->specific_error = 0; 758c2ecf20Sopenharmony_ci phr->version = 0; 768c2ecf20Sopenharmony_ci} 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_civoid hpi_init_message_response(struct hpi_message *phm, 798c2ecf20Sopenharmony_ci struct hpi_response *phr, u16 object, u16 function) 808c2ecf20Sopenharmony_ci{ 818c2ecf20Sopenharmony_ci hpi_init_message(phm, object, function); 828c2ecf20Sopenharmony_ci /* default error return if the response is 838c2ecf20Sopenharmony_ci not filled in by the callee */ 848c2ecf20Sopenharmony_ci hpi_init_response(phr, object, function, 858c2ecf20Sopenharmony_ci HPI_ERROR_PROCESSING_MESSAGE); 868c2ecf20Sopenharmony_ci} 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_cistatic void hpi_init_messageV1(struct hpi_message_header *phm, u16 size, 898c2ecf20Sopenharmony_ci u16 object, u16 function) 908c2ecf20Sopenharmony_ci{ 918c2ecf20Sopenharmony_ci memset(phm, 0, size); 928c2ecf20Sopenharmony_ci if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) { 938c2ecf20Sopenharmony_ci phm->size = size; 948c2ecf20Sopenharmony_ci phm->type = HPI_TYPE_REQUEST; 958c2ecf20Sopenharmony_ci phm->object = object; 968c2ecf20Sopenharmony_ci phm->function = function; 978c2ecf20Sopenharmony_ci phm->version = 1; 988c2ecf20Sopenharmony_ci /* Expect adapter index to be set by caller */ 998c2ecf20Sopenharmony_ci } 1008c2ecf20Sopenharmony_ci} 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_civoid hpi_init_responseV1(struct hpi_response_header *phr, u16 size, 1038c2ecf20Sopenharmony_ci u16 object, u16 function) 1048c2ecf20Sopenharmony_ci{ 1058c2ecf20Sopenharmony_ci (void)object; 1068c2ecf20Sopenharmony_ci (void)function; 1078c2ecf20Sopenharmony_ci memset(phr, 0, size); 1088c2ecf20Sopenharmony_ci phr->size = size; 1098c2ecf20Sopenharmony_ci phr->version = 1; 1108c2ecf20Sopenharmony_ci phr->type = HPI_TYPE_RESPONSE; 1118c2ecf20Sopenharmony_ci phr->error = HPI_ERROR_PROCESSING_MESSAGE; 1128c2ecf20Sopenharmony_ci} 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_civoid hpi_init_message_responseV1(struct hpi_message_header *phm, u16 msg_size, 1158c2ecf20Sopenharmony_ci struct hpi_response_header *phr, u16 res_size, u16 object, 1168c2ecf20Sopenharmony_ci u16 function) 1178c2ecf20Sopenharmony_ci{ 1188c2ecf20Sopenharmony_ci hpi_init_messageV1(phm, msg_size, object, function); 1198c2ecf20Sopenharmony_ci hpi_init_responseV1(phr, res_size, object, function); 1208c2ecf20Sopenharmony_ci} 121