root/sound/pci/asihpi/hpicmn.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hpi_validate_response
  2. hpi_add_adapter
  3. hpi_delete_adapter
  4. hpi_find_adapter
  5. wipe_adapter_list
  6. subsys_get_adapter
  7. control_cache_alloc_check
  8. find_control
  9. hpi_check_control_cache_single
  10. hpi_check_control_cache
  11. hpi_cmn_control_cache_sync_to_msg_single
  12. hpi_cmn_control_cache_sync_to_msg
  13. hpi_alloc_control_cache
  14. hpi_free_control_cache
  15. subsys_message
  16. HPI_COMMON

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

/* [<][>][^][v][top][bottom][index][help] */