Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /******************************************************************************
0003 
0004     AudioScience HPI driver
0005     Copyright (C) 1997-2014  AudioScience Inc. <support@audioscience.com>
0006 
0007 
0008 \file hpicmn.c
0009 
0010  Common functions used by hpixxxx.c modules
0011 
0012 (C) Copyright AudioScience Inc. 1998-2003
0013 *******************************************************************************/
0014 #define SOURCEFILE_NAME "hpicmn.c"
0015 
0016 #include "hpi_internal.h"
0017 #include "hpidebug.h"
0018 #include "hpimsginit.h"
0019 
0020 #include "hpicmn.h"
0021 
0022 struct hpi_adapters_list {
0023     struct hpios_spinlock list_lock;
0024     struct hpi_adapter_obj adapter[HPI_MAX_ADAPTERS];
0025     u16 gw_num_adapters;
0026 };
0027 
0028 static struct hpi_adapters_list adapters;
0029 
0030 /**
0031  * hpi_validate_response - Given an HPI Message that was sent out and
0032  * a response that was received, validate that the response has the
0033  * correct fields filled in, i.e ObjectType, Function etc
0034  * @phm: message
0035  * @phr: response
0036  */
0037 u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr)
0038 {
0039     if (phr->type != HPI_TYPE_RESPONSE) {
0040         HPI_DEBUG_LOG(ERROR, "header type %d invalid\n", phr->type);
0041         return HPI_ERROR_INVALID_RESPONSE;
0042     }
0043 
0044     if (phr->object != phm->object) {
0045         HPI_DEBUG_LOG(ERROR, "header object %d invalid\n",
0046             phr->object);
0047         return HPI_ERROR_INVALID_RESPONSE;
0048     }
0049 
0050     if (phr->function != phm->function) {
0051         HPI_DEBUG_LOG(ERROR, "header function %d invalid\n",
0052             phr->function);
0053         return HPI_ERROR_INVALID_RESPONSE;
0054     }
0055 
0056     return 0;
0057 }
0058 
0059 u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
0060 {
0061     u16 retval = 0;
0062     /*HPI_ASSERT(pao->type); */
0063 
0064     hpios_alistlock_lock(&adapters);
0065 
0066     if (pao->index >= HPI_MAX_ADAPTERS) {
0067         retval = HPI_ERROR_BAD_ADAPTER_NUMBER;
0068         goto unlock;
0069     }
0070 
0071     if (adapters.adapter[pao->index].type) {
0072         int a;
0073         for (a = HPI_MAX_ADAPTERS - 1; a >= 0; a--) {
0074             if (!adapters.adapter[a].type) {
0075                 HPI_DEBUG_LOG(WARNING,
0076                     "ASI%X duplicate index %d moved to %d\n",
0077                     pao->type, pao->index, a);
0078                 pao->index = a;
0079                 break;
0080             }
0081         }
0082         if (a < 0) {
0083             retval = HPI_ERROR_DUPLICATE_ADAPTER_NUMBER;
0084             goto unlock;
0085         }
0086     }
0087     adapters.adapter[pao->index] = *pao;
0088     hpios_dsplock_init(&adapters.adapter[pao->index]);
0089     adapters.gw_num_adapters++;
0090 
0091 unlock:
0092     hpios_alistlock_unlock(&adapters);
0093     return retval;
0094 }
0095 
0096 void hpi_delete_adapter(struct hpi_adapter_obj *pao)
0097 {
0098     if (!pao->type) {
0099         HPI_DEBUG_LOG(ERROR, "removing null adapter?\n");
0100         return;
0101     }
0102 
0103     hpios_alistlock_lock(&adapters);
0104     if (adapters.adapter[pao->index].type)
0105         adapters.gw_num_adapters--;
0106     memset(&adapters.adapter[pao->index], 0, sizeof(adapters.adapter[0]));
0107     hpios_alistlock_unlock(&adapters);
0108 }
0109 
0110 /**
0111  * hpi_find_adapter - FindAdapter returns a pointer to the struct
0112  * hpi_adapter_obj with index wAdapterIndex in an HPI_ADAPTERS_LIST
0113  * structure.
0114  * @adapter_index: value in [0, HPI_MAX_ADAPTERS[
0115  */
0116 struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index)
0117 {
0118     struct hpi_adapter_obj *pao = NULL;
0119 
0120     if (adapter_index >= HPI_MAX_ADAPTERS) {
0121         HPI_DEBUG_LOG(VERBOSE, "find_adapter invalid index %d\n",
0122             adapter_index);
0123         return NULL;
0124     }
0125 
0126     pao = &adapters.adapter[adapter_index];
0127     if (pao->type != 0) {
0128         /*
0129            HPI_DEBUG_LOG(VERBOSE, "Found adapter index %d\n",
0130            wAdapterIndex);
0131          */
0132         return pao;
0133     } else {
0134         /*
0135            HPI_DEBUG_LOG(VERBOSE, "No adapter index %d\n",
0136            wAdapterIndex);
0137          */
0138         return NULL;
0139     }
0140 }
0141 
0142 /**
0143  * wipe_adapter_list - wipe an HPI_ADAPTERS_LIST structure.
0144  *
0145  */
0146 static void wipe_adapter_list(void)
0147 {
0148     memset(&adapters, 0, sizeof(adapters));
0149 }
0150 
0151 static void subsys_get_adapter(struct hpi_message *phm,
0152     struct hpi_response *phr)
0153 {
0154     int count = phm->obj_index;
0155     u16 index = 0;
0156 
0157     /* find the nCount'th nonzero adapter in array */
0158     for (index = 0; index < HPI_MAX_ADAPTERS; index++) {
0159         if (adapters.adapter[index].type) {
0160             if (!count)
0161                 break;
0162             count--;
0163         }
0164     }
0165 
0166     if (index < HPI_MAX_ADAPTERS) {
0167         phr->u.s.adapter_index = adapters.adapter[index].index;
0168         phr->u.s.adapter_type = adapters.adapter[index].type;
0169     } else {
0170         phr->u.s.adapter_index = 0;
0171         phr->u.s.adapter_type = 0;
0172         phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
0173     }
0174 }
0175 
0176 static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
0177 {
0178     unsigned int i;
0179     int cached = 0;
0180     if (!pC)
0181         return 0;
0182 
0183     if (pC->init)
0184         return pC->init;
0185 
0186     if (!pC->p_cache)
0187         return 0;
0188 
0189     if (pC->control_count && pC->cache_size_in_bytes) {
0190         char *p_master_cache;
0191         unsigned int byte_count = 0;
0192 
0193         p_master_cache = (char *)pC->p_cache;
0194         HPI_DEBUG_LOG(DEBUG, "check %d controls\n",
0195             pC->control_count);
0196         for (i = 0; i < pC->control_count; i++) {
0197             struct hpi_control_cache_info *info =
0198                 (struct hpi_control_cache_info *)
0199                 &p_master_cache[byte_count];
0200             u16 control_index = info->control_index;
0201 
0202             if (control_index >= pC->control_count) {
0203                 HPI_DEBUG_LOG(INFO,
0204                     "adap %d control index %d out of range, cache not ready?\n",
0205                     pC->adap_idx, control_index);
0206                 return 0;
0207             }
0208 
0209             if (!info->size_in32bit_words) {
0210                 if (!i) {
0211                     HPI_DEBUG_LOG(INFO,
0212                         "adap %d cache not ready?\n",
0213                         pC->adap_idx);
0214                     return 0;
0215                 }
0216                 /* The cache is invalid.
0217                  * Minimum valid entry size is
0218                  * sizeof(struct hpi_control_cache_info)
0219                  */
0220                 HPI_DEBUG_LOG(ERROR,
0221                     "adap %d zero size cache entry %d\n",
0222                     pC->adap_idx, i);
0223                 break;
0224             }
0225 
0226             if (info->control_type) {
0227                 pC->p_info[control_index] = info;
0228                 cached++;
0229             } else {    /* dummy cache entry */
0230                 pC->p_info[control_index] = NULL;
0231             }
0232 
0233             byte_count += info->size_in32bit_words * 4;
0234 
0235             HPI_DEBUG_LOG(VERBOSE,
0236                 "cached %d, pinfo %p index %d type %d size %d\n",
0237                 cached, pC->p_info[info->control_index],
0238                 info->control_index, info->control_type,
0239                 info->size_in32bit_words);
0240 
0241             /* quit loop early if whole cache has been scanned.
0242              * dwControlCount is the maximum possible entries
0243              * but some may be absent from the cache
0244              */
0245             if (byte_count >= pC->cache_size_in_bytes)
0246                 break;
0247             /* have seen last control index */
0248             if (info->control_index == pC->control_count - 1)
0249                 break;
0250         }
0251 
0252         if (byte_count != pC->cache_size_in_bytes)
0253             HPI_DEBUG_LOG(WARNING,
0254                 "adap %d bytecount %d != cache size %d\n",
0255                 pC->adap_idx, byte_count,
0256                 pC->cache_size_in_bytes);
0257         else
0258             HPI_DEBUG_LOG(DEBUG,
0259                 "adap %d cache good, bytecount == cache size = %d\n",
0260                 pC->adap_idx, byte_count);
0261 
0262         pC->init = (u16)cached;
0263     }
0264     return pC->init;
0265 }
0266 
0267 /** Find a control.
0268 */
0269 static short find_control(u16 control_index,
0270     struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI)
0271 {
0272     if (!control_cache_alloc_check(p_cache)) {
0273         HPI_DEBUG_LOG(VERBOSE,
0274             "control_cache_alloc_check() failed %d\n",
0275             control_index);
0276         return 0;
0277     }
0278 
0279     *pI = p_cache->p_info[control_index];
0280     if (!*pI) {
0281         HPI_DEBUG_LOG(VERBOSE, "Uncached Control %d\n",
0282             control_index);
0283         return 0;
0284     } else {
0285         HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n",
0286             (*pI)->control_type);
0287     }
0288     return 1;
0289 }
0290 
0291 /* allow unified treatment of several string fields within struct */
0292 #define HPICMN_PAD_OFS_AND_SIZE(m)  {\
0293     offsetof(struct hpi_control_cache_pad, m), \
0294     sizeof(((struct hpi_control_cache_pad *)(NULL))->m) }
0295 
0296 struct pad_ofs_size {
0297     unsigned int offset;
0298     unsigned int field_size;
0299 };
0300 
0301 static const struct pad_ofs_size pad_desc[] = {
0302     HPICMN_PAD_OFS_AND_SIZE(c_channel), /* HPI_PAD_CHANNEL_NAME */
0303     HPICMN_PAD_OFS_AND_SIZE(c_artist),  /* HPI_PAD_ARTIST */
0304     HPICMN_PAD_OFS_AND_SIZE(c_title),   /* HPI_PAD_TITLE */
0305     HPICMN_PAD_OFS_AND_SIZE(c_comment), /* HPI_PAD_COMMENT */
0306 };
0307 
0308 /** CheckControlCache checks the cache and fills the struct hpi_response
0309  * accordingly. It returns one if a cache hit occurred, zero otherwise.
0310  */
0311 short hpi_check_control_cache_single(struct hpi_control_cache_single *pC,
0312     struct hpi_message *phm, struct hpi_response *phr)
0313 {
0314     size_t response_size;
0315     short found = 1;
0316 
0317     /* set the default response size */
0318     response_size =
0319         sizeof(struct hpi_response_header) +
0320         sizeof(struct hpi_control_res);
0321 
0322     switch (pC->u.i.control_type) {
0323 
0324     case HPI_CONTROL_METER:
0325         if (phm->u.c.attribute == HPI_METER_PEAK) {
0326             phr->u.c.an_log_value[0] = pC->u.meter.an_log_peak[0];
0327             phr->u.c.an_log_value[1] = pC->u.meter.an_log_peak[1];
0328         } else if (phm->u.c.attribute == HPI_METER_RMS) {
0329             if (pC->u.meter.an_logRMS[0] ==
0330                 HPI_CACHE_INVALID_SHORT) {
0331                 phr->error =
0332                     HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
0333                 phr->u.c.an_log_value[0] = HPI_METER_MINIMUM;
0334                 phr->u.c.an_log_value[1] = HPI_METER_MINIMUM;
0335             } else {
0336                 phr->u.c.an_log_value[0] =
0337                     pC->u.meter.an_logRMS[0];
0338                 phr->u.c.an_log_value[1] =
0339                     pC->u.meter.an_logRMS[1];
0340             }
0341         } else
0342             found = 0;
0343         break;
0344     case HPI_CONTROL_VOLUME:
0345         if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
0346             phr->u.c.an_log_value[0] = pC->u.vol.an_log[0];
0347             phr->u.c.an_log_value[1] = pC->u.vol.an_log[1];
0348         } else if (phm->u.c.attribute == HPI_VOLUME_MUTE) {
0349             if (pC->u.vol.flags & HPI_VOLUME_FLAG_HAS_MUTE) {
0350                 if (pC->u.vol.flags & HPI_VOLUME_FLAG_MUTED)
0351                     phr->u.c.param1 =
0352                         HPI_BITMASK_ALL_CHANNELS;
0353                 else
0354                     phr->u.c.param1 = 0;
0355             } else {
0356                 phr->error =
0357                     HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
0358                 phr->u.c.param1 = 0;
0359             }
0360         } else {
0361             found = 0;
0362         }
0363         break;
0364     case HPI_CONTROL_MULTIPLEXER:
0365         if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
0366             phr->u.c.param1 = pC->u.mux.source_node_type;
0367             phr->u.c.param2 = pC->u.mux.source_node_index;
0368         } else {
0369             found = 0;
0370         }
0371         break;
0372     case HPI_CONTROL_CHANNEL_MODE:
0373         if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
0374             phr->u.c.param1 = pC->u.mode.mode;
0375         else
0376             found = 0;
0377         break;
0378     case HPI_CONTROL_LEVEL:
0379         if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
0380             phr->u.c.an_log_value[0] = pC->u.level.an_log[0];
0381             phr->u.c.an_log_value[1] = pC->u.level.an_log[1];
0382         } else
0383             found = 0;
0384         break;
0385     case HPI_CONTROL_TUNER:
0386         if (phm->u.c.attribute == HPI_TUNER_FREQ)
0387             phr->u.c.param1 = pC->u.tuner.freq_ink_hz;
0388         else if (phm->u.c.attribute == HPI_TUNER_BAND)
0389             phr->u.c.param1 = pC->u.tuner.band;
0390         else if (phm->u.c.attribute == HPI_TUNER_LEVEL_AVG)
0391             if (pC->u.tuner.s_level_avg ==
0392                 HPI_CACHE_INVALID_SHORT) {
0393                 phr->u.cu.tuner.s_level = 0;
0394                 phr->error =
0395                     HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
0396             } else
0397                 phr->u.cu.tuner.s_level =
0398                     pC->u.tuner.s_level_avg;
0399         else
0400             found = 0;
0401         break;
0402     case HPI_CONTROL_AESEBU_RECEIVER:
0403         if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS)
0404             phr->u.c.param1 = pC->u.aes3rx.error_status;
0405         else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
0406             phr->u.c.param1 = pC->u.aes3rx.format;
0407         else
0408             found = 0;
0409         break;
0410     case HPI_CONTROL_AESEBU_TRANSMITTER:
0411         if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
0412             phr->u.c.param1 = pC->u.aes3tx.format;
0413         else
0414             found = 0;
0415         break;
0416     case HPI_CONTROL_TONEDETECTOR:
0417         if (phm->u.c.attribute == HPI_TONEDETECTOR_STATE)
0418             phr->u.c.param1 = pC->u.tone.state;
0419         else
0420             found = 0;
0421         break;
0422     case HPI_CONTROL_SILENCEDETECTOR:
0423         if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) {
0424             phr->u.c.param1 = pC->u.silence.state;
0425         } else
0426             found = 0;
0427         break;
0428     case HPI_CONTROL_MICROPHONE:
0429         if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
0430             phr->u.c.param1 = pC->u.microphone.phantom_state;
0431         else
0432             found = 0;
0433         break;
0434     case HPI_CONTROL_SAMPLECLOCK:
0435         if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
0436             phr->u.c.param1 = pC->u.clk.source;
0437         else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) {
0438             if (pC->u.clk.source_index ==
0439                 HPI_CACHE_INVALID_UINT16) {
0440                 phr->u.c.param1 = 0;
0441                 phr->error =
0442                     HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
0443             } else
0444                 phr->u.c.param1 = pC->u.clk.source_index;
0445         } else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
0446             phr->u.c.param1 = pC->u.clk.sample_rate;
0447         else
0448             found = 0;
0449         break;
0450     case HPI_CONTROL_PAD:{
0451             struct hpi_control_cache_pad *p_pad;
0452             p_pad = (struct hpi_control_cache_pad *)pC;
0453 
0454             if (!(p_pad->field_valid_flags & (1 <<
0455                         HPI_CTL_ATTR_INDEX(phm->u.c.
0456                             attribute)))) {
0457                 phr->error =
0458                     HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
0459                 break;
0460             }
0461 
0462             if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID)
0463                 phr->u.c.param1 = p_pad->pI;
0464             else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE)
0465                 phr->u.c.param1 = p_pad->pTY;
0466             else {
0467                 unsigned int index =
0468                     HPI_CTL_ATTR_INDEX(phm->u.c.
0469                     attribute) - 1;
0470                 unsigned int offset = phm->u.c.param1;
0471                 unsigned int pad_string_len, field_size;
0472                 char *pad_string;
0473                 unsigned int tocopy;
0474 
0475                 if (index > ARRAY_SIZE(pad_desc) - 1) {
0476                     phr->error =
0477                         HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
0478                     break;
0479                 }
0480 
0481                 pad_string =
0482                     ((char *)p_pad) +
0483                     pad_desc[index].offset;
0484                 field_size = pad_desc[index].field_size;
0485                 /* Ensure null terminator */
0486                 pad_string[field_size - 1] = 0;
0487 
0488                 pad_string_len = strlen(pad_string) + 1;
0489 
0490                 if (offset > pad_string_len) {
0491                     phr->error =
0492                         HPI_ERROR_INVALID_CONTROL_VALUE;
0493                     break;
0494                 }
0495 
0496                 tocopy = pad_string_len - offset;
0497                 if (tocopy > sizeof(phr->u.cu.chars8.sz_data))
0498                     tocopy = sizeof(phr->u.cu.chars8.
0499                         sz_data);
0500 
0501                 memcpy(phr->u.cu.chars8.sz_data,
0502                     &pad_string[offset], tocopy);
0503 
0504                 phr->u.cu.chars8.remaining_chars =
0505                     pad_string_len - offset - tocopy;
0506             }
0507         }
0508         break;
0509     default:
0510         found = 0;
0511         break;
0512     }
0513 
0514     HPI_DEBUG_LOG(VERBOSE, "%s Adap %d, Ctl %d, Type %d, Attr %d\n",
0515         found ? "Cached" : "Uncached", phm->adapter_index,
0516         pC->u.i.control_index, pC->u.i.control_type,
0517         phm->u.c.attribute);
0518 
0519     if (found) {
0520         phr->size = (u16)response_size;
0521         phr->type = HPI_TYPE_RESPONSE;
0522         phr->object = phm->object;
0523         phr->function = phm->function;
0524     }
0525 
0526     return found;
0527 }
0528 
0529 short hpi_check_control_cache(struct hpi_control_cache *p_cache,
0530     struct hpi_message *phm, struct hpi_response *phr)
0531 {
0532     struct hpi_control_cache_info *pI;
0533 
0534     if (!find_control(phm->obj_index, p_cache, &pI)) {
0535         HPI_DEBUG_LOG(VERBOSE,
0536             "HPICMN find_control() failed for adap %d\n",
0537             phm->adapter_index);
0538         return 0;
0539     }
0540 
0541     phr->error = 0;
0542     phr->specific_error = 0;
0543     phr->version = 0;
0544 
0545     return hpi_check_control_cache_single((struct hpi_control_cache_single
0546             *)pI, phm, phr);
0547 }
0548 
0549 /** Updates the cache with Set values.
0550 
0551 Only update if no error.
0552 Volume and Level return the limited values in the response, so use these
0553 Multiplexer does so use sent values
0554 */
0555 void hpi_cmn_control_cache_sync_to_msg_single(struct hpi_control_cache_single
0556     *pC, struct hpi_message *phm, struct hpi_response *phr)
0557 {
0558     switch (pC->u.i.control_type) {
0559     case HPI_CONTROL_VOLUME:
0560         if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
0561             pC->u.vol.an_log[0] = phr->u.c.an_log_value[0];
0562             pC->u.vol.an_log[1] = phr->u.c.an_log_value[1];
0563         } else if (phm->u.c.attribute == HPI_VOLUME_MUTE) {
0564             if (phm->u.c.param1)
0565                 pC->u.vol.flags |= HPI_VOLUME_FLAG_MUTED;
0566             else
0567                 pC->u.vol.flags &= ~HPI_VOLUME_FLAG_MUTED;
0568         }
0569         break;
0570     case HPI_CONTROL_MULTIPLEXER:
0571         /* mux does not return its setting on Set command. */
0572         if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
0573             pC->u.mux.source_node_type = (u16)phm->u.c.param1;
0574             pC->u.mux.source_node_index = (u16)phm->u.c.param2;
0575         }
0576         break;
0577     case HPI_CONTROL_CHANNEL_MODE:
0578         /* mode does not return its setting on Set command. */
0579         if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
0580             pC->u.mode.mode = (u16)phm->u.c.param1;
0581         break;
0582     case HPI_CONTROL_LEVEL:
0583         if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
0584             pC->u.vol.an_log[0] = phr->u.c.an_log_value[0];
0585             pC->u.vol.an_log[1] = phr->u.c.an_log_value[1];
0586         }
0587         break;
0588     case HPI_CONTROL_MICROPHONE:
0589         if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
0590             pC->u.microphone.phantom_state = (u16)phm->u.c.param1;
0591         break;
0592     case HPI_CONTROL_AESEBU_TRANSMITTER:
0593         if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
0594             pC->u.aes3tx.format = phm->u.c.param1;
0595         break;
0596     case HPI_CONTROL_AESEBU_RECEIVER:
0597         if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
0598             pC->u.aes3rx.format = phm->u.c.param1;
0599         break;
0600     case HPI_CONTROL_SAMPLECLOCK:
0601         if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
0602             pC->u.clk.source = (u16)phm->u.c.param1;
0603         else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX)
0604             pC->u.clk.source_index = (u16)phm->u.c.param1;
0605         else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
0606             pC->u.clk.sample_rate = phm->u.c.param1;
0607         break;
0608     default:
0609         break;
0610     }
0611 }
0612 
0613 void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache,
0614     struct hpi_message *phm, struct hpi_response *phr)
0615 {
0616     struct hpi_control_cache_single *pC;
0617     struct hpi_control_cache_info *pI;
0618 
0619     if (phr->error)
0620         return;
0621 
0622     if (!find_control(phm->obj_index, p_cache, &pI)) {
0623         HPI_DEBUG_LOG(VERBOSE,
0624             "HPICMN find_control() failed for adap %d\n",
0625             phm->adapter_index);
0626         return;
0627     }
0628 
0629     /* pC is the default cached control strucure.
0630        May be cast to something else in the following switch statement.
0631      */
0632     pC = (struct hpi_control_cache_single *)pI;
0633 
0634     hpi_cmn_control_cache_sync_to_msg_single(pC, phm, phr);
0635 }
0636 
0637 /** Allocate control cache.
0638 
0639 \return Cache pointer, or NULL if allocation fails.
0640 */
0641 struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count,
0642     const u32 size_in_bytes, u8 *p_dsp_control_buffer)
0643 {
0644     struct hpi_control_cache *p_cache =
0645         kmalloc(sizeof(*p_cache), GFP_KERNEL);
0646     if (!p_cache)
0647         return NULL;
0648 
0649     p_cache->p_info =
0650         kcalloc(control_count, sizeof(*p_cache->p_info), GFP_KERNEL);
0651     if (!p_cache->p_info) {
0652         kfree(p_cache);
0653         return NULL;
0654     }
0655 
0656     p_cache->cache_size_in_bytes = size_in_bytes;
0657     p_cache->control_count = control_count;
0658     p_cache->p_cache = p_dsp_control_buffer;
0659     p_cache->init = 0;
0660     return p_cache;
0661 }
0662 
0663 void hpi_free_control_cache(struct hpi_control_cache *p_cache)
0664 {
0665     if (p_cache) {
0666         kfree(p_cache->p_info);
0667         kfree(p_cache);
0668     }
0669 }
0670 
0671 static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
0672 {
0673     hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, 0);
0674 
0675     switch (phm->function) {
0676     case HPI_SUBSYS_OPEN:
0677     case HPI_SUBSYS_CLOSE:
0678     case HPI_SUBSYS_DRIVER_UNLOAD:
0679         break;
0680     case HPI_SUBSYS_DRIVER_LOAD:
0681         wipe_adapter_list();
0682         hpios_alistlock_init(&adapters);
0683         break;
0684     case HPI_SUBSYS_GET_ADAPTER:
0685         subsys_get_adapter(phm, phr);
0686         break;
0687     case HPI_SUBSYS_GET_NUM_ADAPTERS:
0688         phr->u.s.num_adapters = adapters.gw_num_adapters;
0689         break;
0690     case HPI_SUBSYS_CREATE_ADAPTER:
0691         break;
0692     default:
0693         phr->error = HPI_ERROR_INVALID_FUNC;
0694         break;
0695     }
0696 }
0697 
0698 void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr)
0699 {
0700     switch (phm->type) {
0701     case HPI_TYPE_REQUEST:
0702         switch (phm->object) {
0703         case HPI_OBJ_SUBSYSTEM:
0704             subsys_message(phm, phr);
0705             break;
0706         }
0707         break;
0708 
0709     default:
0710         phr->error = HPI_ERROR_INVALID_TYPE;
0711         break;
0712     }
0713 }