Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)     AudioScience HPI driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)     Copyright (C) 1997-2014  AudioScience Inc. <support@audioscience.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) \file hpicmn.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  Common functions used by hpixxxx.c modules
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) (C) Copyright AudioScience Inc. 1998-2003
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) *******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #define SOURCEFILE_NAME "hpicmn.c"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include "hpi_internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include "hpidebug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include "hpimsginit.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include "hpicmn.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) struct hpi_adapters_list {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	struct hpios_spinlock list_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	struct hpi_adapter_obj adapter[HPI_MAX_ADAPTERS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	u16 gw_num_adapters;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) static struct hpi_adapters_list adapters;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * hpi_validate_response - Given an HPI Message that was sent out and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * a response that was received, validate that the response has the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * correct fields filled in, i.e ObjectType, Function etc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  * @phm: message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  * @phr: response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	if (phr->type != HPI_TYPE_RESPONSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		HPI_DEBUG_LOG(ERROR, "header type %d invalid\n", phr->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		return HPI_ERROR_INVALID_RESPONSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	if (phr->object != phm->object) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 		HPI_DEBUG_LOG(ERROR, "header object %d invalid\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 			phr->object);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		return HPI_ERROR_INVALID_RESPONSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	if (phr->function != phm->function) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		HPI_DEBUG_LOG(ERROR, "header function %d invalid\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 			phr->function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		return HPI_ERROR_INVALID_RESPONSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	u16 retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	/*HPI_ASSERT(pao->type); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	hpios_alistlock_lock(&adapters);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	if (pao->index >= HPI_MAX_ADAPTERS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		retval = HPI_ERROR_BAD_ADAPTER_NUMBER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	if (adapters.adapter[pao->index].type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		int a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		for (a = HPI_MAX_ADAPTERS - 1; a >= 0; a--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 			if (!adapters.adapter[a].type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 				HPI_DEBUG_LOG(WARNING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 					"ASI%X duplicate index %d moved to %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 					pao->type, pao->index, a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 				pao->index = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		if (a < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 			retval = HPI_ERROR_DUPLICATE_ADAPTER_NUMBER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 			goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	adapters.adapter[pao->index] = *pao;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	hpios_dsplock_init(&adapters.adapter[pao->index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	adapters.gw_num_adapters++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	hpios_alistlock_unlock(&adapters);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) void hpi_delete_adapter(struct hpi_adapter_obj *pao)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	if (!pao->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		HPI_DEBUG_LOG(ERROR, "removing null adapter?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	hpios_alistlock_lock(&adapters);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	if (adapters.adapter[pao->index].type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		adapters.gw_num_adapters--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	memset(&adapters.adapter[pao->index], 0, sizeof(adapters.adapter[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	hpios_alistlock_unlock(&adapters);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)  * hpi_find_adapter - FindAdapter returns a pointer to the struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)  * hpi_adapter_obj with index wAdapterIndex in an HPI_ADAPTERS_LIST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)  * structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)  * @adapter_index: value in [0, HPI_MAX_ADAPTERS[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	struct hpi_adapter_obj *pao = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	if (adapter_index >= HPI_MAX_ADAPTERS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		HPI_DEBUG_LOG(VERBOSE, "find_adapter invalid index %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 			adapter_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	pao = &adapters.adapter[adapter_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	if (pao->type != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		   HPI_DEBUG_LOG(VERBOSE, "Found adapter index %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		   wAdapterIndex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		return pao;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		   HPI_DEBUG_LOG(VERBOSE, "No adapter index %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		   wAdapterIndex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  * wipe_adapter_list - wipe an HPI_ADAPTERS_LIST structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static void wipe_adapter_list(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	memset(&adapters, 0, sizeof(adapters));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static void subsys_get_adapter(struct hpi_message *phm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	struct hpi_response *phr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	int count = phm->obj_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	u16 index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	/* find the nCount'th nonzero adapter in array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	for (index = 0; index < HPI_MAX_ADAPTERS; index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		if (adapters.adapter[index].type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 			if (!count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	if (index < HPI_MAX_ADAPTERS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		phr->u.s.adapter_index = adapters.adapter[index].index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		phr->u.s.adapter_type = adapters.adapter[index].type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		phr->u.s.adapter_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		phr->u.s.adapter_type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	int cached = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	if (!pC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	if (pC->init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		return pC->init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	if (!pC->p_cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	if (pC->control_count && pC->cache_size_in_bytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		char *p_master_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		unsigned int byte_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		p_master_cache = (char *)pC->p_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		HPI_DEBUG_LOG(DEBUG, "check %d controls\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 			pC->control_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		for (i = 0; i < pC->control_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 			struct hpi_control_cache_info *info =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 				(struct hpi_control_cache_info *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 				&p_master_cache[byte_count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 			u16 control_index = info->control_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 			if (control_index >= pC->control_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 				HPI_DEBUG_LOG(INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 					"adap %d control index %d out of range, cache not ready?\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 					pC->adap_idx, control_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 			if (!info->size_in32bit_words) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 				if (!i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 					HPI_DEBUG_LOG(INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 						"adap %d cache not ready?\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 						pC->adap_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 					return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 				/* The cache is invalid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 				 * Minimum valid entry size is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 				 * sizeof(struct hpi_control_cache_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 				HPI_DEBUG_LOG(ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 					"adap %d zero size cache entry %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 					pC->adap_idx, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 			if (info->control_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 				pC->p_info[control_index] = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 				cached++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 			} else {	/* dummy cache entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 				pC->p_info[control_index] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 			byte_count += info->size_in32bit_words * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 			HPI_DEBUG_LOG(VERBOSE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 				"cached %d, pinfo %p index %d type %d size %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 				cached, pC->p_info[info->control_index],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 				info->control_index, info->control_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 				info->size_in32bit_words);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 			/* quit loop early if whole cache has been scanned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 			 * dwControlCount is the maximum possible entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 			 * but some may be absent from the cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 			if (byte_count >= pC->cache_size_in_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 			/* have seen last control index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 			if (info->control_index == pC->control_count - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		if (byte_count != pC->cache_size_in_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 			HPI_DEBUG_LOG(WARNING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 				"adap %d bytecount %d != cache size %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 				pC->adap_idx, byte_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 				pC->cache_size_in_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 			HPI_DEBUG_LOG(DEBUG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 				"adap %d cache good, bytecount == cache size = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 				pC->adap_idx, byte_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		pC->init = (u16)cached;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	return pC->init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) /** Find a control.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static short find_control(u16 control_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	if (!control_cache_alloc_check(p_cache)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		HPI_DEBUG_LOG(VERBOSE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 			"control_cache_alloc_check() failed %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 			control_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	*pI = p_cache->p_info[control_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	if (!*pI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		HPI_DEBUG_LOG(VERBOSE, "Uncached Control %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 			control_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 			(*pI)->control_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /* allow unified treatment of several string fields within struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) #define HPICMN_PAD_OFS_AND_SIZE(m)  {\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	offsetof(struct hpi_control_cache_pad, m), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	sizeof(((struct hpi_control_cache_pad *)(NULL))->m) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct pad_ofs_size {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	unsigned int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	unsigned int field_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static const struct pad_ofs_size pad_desc[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	HPICMN_PAD_OFS_AND_SIZE(c_channel),	/* HPI_PAD_CHANNEL_NAME */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	HPICMN_PAD_OFS_AND_SIZE(c_artist),	/* HPI_PAD_ARTIST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	HPICMN_PAD_OFS_AND_SIZE(c_title),	/* HPI_PAD_TITLE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	HPICMN_PAD_OFS_AND_SIZE(c_comment),	/* HPI_PAD_COMMENT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /** CheckControlCache checks the cache and fills the struct hpi_response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)  * accordingly. It returns one if a cache hit occurred, zero otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) short hpi_check_control_cache_single(struct hpi_control_cache_single *pC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	struct hpi_message *phm, struct hpi_response *phr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	size_t response_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	short found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	/* set the default response size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	response_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		sizeof(struct hpi_response_header) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		sizeof(struct hpi_control_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	switch (pC->u.i.control_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	case HPI_CONTROL_METER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		if (phm->u.c.attribute == HPI_METER_PEAK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 			phr->u.c.an_log_value[0] = pC->u.meter.an_log_peak[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 			phr->u.c.an_log_value[1] = pC->u.meter.an_log_peak[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 		} else if (phm->u.c.attribute == HPI_METER_RMS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 			if (pC->u.meter.an_logRMS[0] ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 				HPI_CACHE_INVALID_SHORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 				phr->error =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 					HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 				phr->u.c.an_log_value[0] = HPI_METER_MINIMUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 				phr->u.c.an_log_value[1] = HPI_METER_MINIMUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 				phr->u.c.an_log_value[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 					pC->u.meter.an_logRMS[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 				phr->u.c.an_log_value[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 					pC->u.meter.an_logRMS[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 			found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	case HPI_CONTROL_VOLUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 			phr->u.c.an_log_value[0] = pC->u.vol.an_log[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 			phr->u.c.an_log_value[1] = pC->u.vol.an_log[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		} else if (phm->u.c.attribute == HPI_VOLUME_MUTE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 			if (pC->u.vol.flags & HPI_VOLUME_FLAG_HAS_MUTE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 				if (pC->u.vol.flags & HPI_VOLUME_FLAG_MUTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 					phr->u.c.param1 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 						HPI_BITMASK_ALL_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 					phr->u.c.param1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 				phr->error =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 					HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 				phr->u.c.param1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 			found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	case HPI_CONTROL_MULTIPLEXER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 		if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 			phr->u.c.param1 = pC->u.mux.source_node_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 			phr->u.c.param2 = pC->u.mux.source_node_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 			found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	case HPI_CONTROL_CHANNEL_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 			phr->u.c.param1 = pC->u.mode.mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 			found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	case HPI_CONTROL_LEVEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 		if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 			phr->u.c.an_log_value[0] = pC->u.level.an_log[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 			phr->u.c.an_log_value[1] = pC->u.level.an_log[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 			found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	case HPI_CONTROL_TUNER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		if (phm->u.c.attribute == HPI_TUNER_FREQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 			phr->u.c.param1 = pC->u.tuner.freq_ink_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		else if (phm->u.c.attribute == HPI_TUNER_BAND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 			phr->u.c.param1 = pC->u.tuner.band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 		else if (phm->u.c.attribute == HPI_TUNER_LEVEL_AVG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 			if (pC->u.tuner.s_level_avg ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 				HPI_CACHE_INVALID_SHORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 				phr->u.cu.tuner.s_level = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 				phr->error =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 					HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 				phr->u.cu.tuner.s_level =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 					pC->u.tuner.s_level_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 			found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	case HPI_CONTROL_AESEBU_RECEIVER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 		if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 			phr->u.c.param1 = pC->u.aes3rx.error_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 			phr->u.c.param1 = pC->u.aes3rx.format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 			found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	case HPI_CONTROL_AESEBU_TRANSMITTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 			phr->u.c.param1 = pC->u.aes3tx.format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 			found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	case HPI_CONTROL_TONEDETECTOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 		if (phm->u.c.attribute == HPI_TONEDETECTOR_STATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 			phr->u.c.param1 = pC->u.tone.state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 			found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	case HPI_CONTROL_SILENCEDETECTOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 			phr->u.c.param1 = pC->u.silence.state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 			found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	case HPI_CONTROL_MICROPHONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 			phr->u.c.param1 = pC->u.microphone.phantom_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 			found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	case HPI_CONTROL_SAMPLECLOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 			phr->u.c.param1 = pC->u.clk.source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 			if (pC->u.clk.source_index ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 				HPI_CACHE_INVALID_UINT16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 				phr->u.c.param1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 				phr->error =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 					HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 				phr->u.c.param1 = pC->u.clk.source_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		} else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 			phr->u.c.param1 = pC->u.clk.sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 			found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	case HPI_CONTROL_PAD:{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 			struct hpi_control_cache_pad *p_pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 			p_pad = (struct hpi_control_cache_pad *)pC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 			if (!(p_pad->field_valid_flags & (1 <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 						HPI_CTL_ATTR_INDEX(phm->u.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 							attribute)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 				phr->error =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 					HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 			if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 				phr->u.c.param1 = p_pad->pI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 			else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 				phr->u.c.param1 = p_pad->pTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 				unsigned int index =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 					HPI_CTL_ATTR_INDEX(phm->u.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 					attribute) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 				unsigned int offset = phm->u.c.param1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 				unsigned int pad_string_len, field_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 				char *pad_string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 				unsigned int tocopy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 				if (index > ARRAY_SIZE(pad_desc) - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 					phr->error =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 						HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 				pad_string =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 					((char *)p_pad) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 					pad_desc[index].offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 				field_size = pad_desc[index].field_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 				/* Ensure null terminator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 				pad_string[field_size - 1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 				pad_string_len = strlen(pad_string) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 				if (offset > pad_string_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 					phr->error =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 						HPI_ERROR_INVALID_CONTROL_VALUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 				tocopy = pad_string_len - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 				if (tocopy > sizeof(phr->u.cu.chars8.sz_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 					tocopy = sizeof(phr->u.cu.chars8.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 						sz_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 				memcpy(phr->u.cu.chars8.sz_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 					&pad_string[offset], tocopy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 				phr->u.cu.chars8.remaining_chars =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 					pad_string_len - offset - tocopy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 		found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	HPI_DEBUG_LOG(VERBOSE, "%s Adap %d, Ctl %d, Type %d, Attr %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		found ? "Cached" : "Uncached", phm->adapter_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		pC->u.i.control_index, pC->u.i.control_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		phm->u.c.attribute);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	if (found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 		phr->size = (u16)response_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		phr->type = HPI_TYPE_RESPONSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 		phr->object = phm->object;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 		phr->function = phm->function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	return found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) short hpi_check_control_cache(struct hpi_control_cache *p_cache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	struct hpi_message *phm, struct hpi_response *phr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	struct hpi_control_cache_info *pI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	if (!find_control(phm->obj_index, p_cache, &pI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 		HPI_DEBUG_LOG(VERBOSE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 			"HPICMN find_control() failed for adap %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 			phm->adapter_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	phr->error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	phr->specific_error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	phr->version = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	return hpi_check_control_cache_single((struct hpi_control_cache_single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 			*)pI, phm, phr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) /** Updates the cache with Set values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) Only update if no error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) Volume and Level return the limited values in the response, so use these
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) Multiplexer does so use sent values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) void hpi_cmn_control_cache_sync_to_msg_single(struct hpi_control_cache_single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	*pC, struct hpi_message *phm, struct hpi_response *phr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	switch (pC->u.i.control_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	case HPI_CONTROL_VOLUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 		if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 			pC->u.vol.an_log[0] = phr->u.c.an_log_value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 			pC->u.vol.an_log[1] = phr->u.c.an_log_value[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 		} else if (phm->u.c.attribute == HPI_VOLUME_MUTE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 			if (phm->u.c.param1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 				pC->u.vol.flags |= HPI_VOLUME_FLAG_MUTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 				pC->u.vol.flags &= ~HPI_VOLUME_FLAG_MUTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	case HPI_CONTROL_MULTIPLEXER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 		/* mux does not return its setting on Set command. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 		if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 			pC->u.mux.source_node_type = (u16)phm->u.c.param1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 			pC->u.mux.source_node_index = (u16)phm->u.c.param2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	case HPI_CONTROL_CHANNEL_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 		/* mode does not return its setting on Set command. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 		if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 			pC->u.mode.mode = (u16)phm->u.c.param1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	case HPI_CONTROL_LEVEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 		if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 			pC->u.vol.an_log[0] = phr->u.c.an_log_value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 			pC->u.vol.an_log[1] = phr->u.c.an_log_value[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	case HPI_CONTROL_MICROPHONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 		if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 			pC->u.microphone.phantom_state = (u16)phm->u.c.param1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	case HPI_CONTROL_AESEBU_TRANSMITTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 		if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 			pC->u.aes3tx.format = phm->u.c.param1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	case HPI_CONTROL_AESEBU_RECEIVER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 		if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 			pC->u.aes3rx.format = phm->u.c.param1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	case HPI_CONTROL_SAMPLECLOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 		if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 			pC->u.clk.source = (u16)phm->u.c.param1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 		else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 			pC->u.clk.source_index = (u16)phm->u.c.param1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 		else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 			pC->u.clk.sample_rate = phm->u.c.param1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	struct hpi_message *phm, struct hpi_response *phr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	struct hpi_control_cache_single *pC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	struct hpi_control_cache_info *pI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	if (phr->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	if (!find_control(phm->obj_index, p_cache, &pI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 		HPI_DEBUG_LOG(VERBOSE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 			"HPICMN find_control() failed for adap %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 			phm->adapter_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	/* pC is the default cached control strucure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	   May be cast to something else in the following switch statement.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	pC = (struct hpi_control_cache_single *)pI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	hpi_cmn_control_cache_sync_to_msg_single(pC, phm, phr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) /** Allocate control cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) \return Cache pointer, or NULL if allocation fails.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	const u32 size_in_bytes, u8 *p_dsp_control_buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	struct hpi_control_cache *p_cache =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 		kmalloc(sizeof(*p_cache), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	if (!p_cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	p_cache->p_info =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 		kcalloc(control_count, sizeof(*p_cache->p_info), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	if (!p_cache->p_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 		kfree(p_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	p_cache->cache_size_in_bytes = size_in_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	p_cache->control_count = control_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	p_cache->p_cache = p_dsp_control_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	p_cache->init = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	return p_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) void hpi_free_control_cache(struct hpi_control_cache *p_cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	if (p_cache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 		kfree(p_cache->p_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 		kfree(p_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	switch (phm->function) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 	case HPI_SUBSYS_OPEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	case HPI_SUBSYS_CLOSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	case HPI_SUBSYS_DRIVER_UNLOAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 	case HPI_SUBSYS_DRIVER_LOAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 		wipe_adapter_list();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 		hpios_alistlock_init(&adapters);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	case HPI_SUBSYS_GET_ADAPTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 		subsys_get_adapter(phm, phr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	case HPI_SUBSYS_GET_NUM_ADAPTERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 		phr->u.s.num_adapters = adapters.gw_num_adapters;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	case HPI_SUBSYS_CREATE_ADAPTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 		phr->error = HPI_ERROR_INVALID_FUNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	switch (phm->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	case HPI_TYPE_REQUEST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 		switch (phm->object) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 		case HPI_OBJ_SUBSYSTEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 			subsys_message(phm, phr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 		phr->error = HPI_ERROR_INVALID_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }