^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) }