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