ALSA: asihpi - Fix minor typos and spelling
[pandora-kernel.git] / sound / pci / asihpi / hpicmn.c
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
33 struct 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
39 static 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 **/
46 u16 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 function %d invalid\n",
61                         phr->function);
62                 return HPI_ERROR_INVALID_RESPONSE;
63         }
64
65         return 0;
66 }
67
68 u16 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
100 unlock:
101         hpios_alistlock_unlock(&adapters);
102         return retval;
103 }
104
105 void 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 */
124 struct 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 **/
155 static void wipe_adapter_list(void)
156 {
157         memset(&adapters, 0, sizeof(adapters));
158 }
159
160 static 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
185 static 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
234                         byte_count += info->size_in32bit_words * 4;
235
236                         HPI_DEBUG_LOG(VERBOSE,
237                                 "cached %d, pinfo %p index %d type %d size %d\n",
238                                 cached, pC->p_info[info->control_index],
239                                 info->control_index, info->control_type,
240                                 info->size_in32bit_words);
241
242                         /* quit loop early if whole cache has been scanned.
243                          * dwControlCount is the maximum possible entries
244                          * but some may be absent from the cache
245                          */
246                         if (byte_count >= pC->cache_size_in_bytes)
247                                 break;
248                         /* have seen last control index */
249                         if (info->control_index == pC->control_count - 1)
250                                 break;
251                 }
252
253                 if (byte_count != pC->cache_size_in_bytes)
254                         HPI_DEBUG_LOG(WARNING,
255                                 "adap %d bytecount %d != cache size %d\n",
256                                 pC->adap_idx, byte_count,
257                                 pC->cache_size_in_bytes);
258                 else
259                         HPI_DEBUG_LOG(DEBUG,
260                                 "adap %d cache good, bytecount == cache size = %d\n",
261                                 pC->adap_idx, byte_count);
262
263                 pC->init = (u16)cached;
264         }
265         return pC->init;
266 }
267
268 /** Find a control.
269 */
270 static short find_control(u16 control_index,
271         struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI)
272 {
273         if (!control_cache_alloc_check(p_cache)) {
274                 HPI_DEBUG_LOG(VERBOSE,
275                         "control_cache_alloc_check() failed %d\n",
276                         control_index);
277                 return 0;
278         }
279
280         *pI = p_cache->p_info[control_index];
281         if (!*pI) {
282                 HPI_DEBUG_LOG(VERBOSE, "Uncached Control %d\n",
283                         control_index);
284                 return 0;
285         } else {
286                 HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n",
287                         (*pI)->control_type);
288         }
289         return 1;
290 }
291
292 /* allow unified treatment of several string fields within struct */
293 #define HPICMN_PAD_OFS_AND_SIZE(m)  {\
294         offsetof(struct hpi_control_cache_pad, m), \
295         sizeof(((struct hpi_control_cache_pad *)(NULL))->m) }
296
297 struct pad_ofs_size {
298         unsigned int offset;
299         unsigned int field_size;
300 };
301
302 static const struct pad_ofs_size pad_desc[] = {
303         HPICMN_PAD_OFS_AND_SIZE(c_channel),     /* HPI_PAD_CHANNEL_NAME */
304         HPICMN_PAD_OFS_AND_SIZE(c_artist),      /* HPI_PAD_ARTIST */
305         HPICMN_PAD_OFS_AND_SIZE(c_title),       /* HPI_PAD_TITLE */
306         HPICMN_PAD_OFS_AND_SIZE(c_comment),     /* HPI_PAD_COMMENT */
307 };
308
309 /** CheckControlCache checks the cache and fills the struct hpi_response
310  * accordingly. It returns one if a cache hit occurred, zero otherwise.
311  */
312 short hpi_check_control_cache(struct hpi_control_cache *p_cache,
313         struct hpi_message *phm, struct hpi_response *phr)
314 {
315         short found = 1;
316         struct hpi_control_cache_info *pI;
317         struct hpi_control_cache_single *pC;
318         u16 response_size;
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         /* set the default response size */
329         response_size =
330                 sizeof(struct hpi_response_header) +
331                 sizeof(struct hpi_control_res);
332
333         /* pC is the default cached control strucure. May be cast to
334            something else in the following switch statement.
335          */
336         pC = (struct hpi_control_cache_single *)pI;
337
338         switch (pI->control_type) {
339
340         case HPI_CONTROL_METER:
341                 if (phm->u.c.attribute == HPI_METER_PEAK) {
342                         phr->u.c.an_log_value[0] = pC->u.meter.an_log_peak[0];
343                         phr->u.c.an_log_value[1] = pC->u.meter.an_log_peak[1];
344                 } else if (phm->u.c.attribute == HPI_METER_RMS) {
345                         if (pC->u.meter.an_logRMS[0] ==
346                                 HPI_CACHE_INVALID_SHORT) {
347                                 phr->error =
348                                         HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
349                                 phr->u.c.an_log_value[0] = HPI_METER_MINIMUM;
350                                 phr->u.c.an_log_value[1] = HPI_METER_MINIMUM;
351                         } else {
352                                 phr->u.c.an_log_value[0] =
353                                         pC->u.meter.an_logRMS[0];
354                                 phr->u.c.an_log_value[1] =
355                                         pC->u.meter.an_logRMS[1];
356                         }
357                 } else
358                         found = 0;
359                 break;
360         case HPI_CONTROL_VOLUME:
361                 if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
362                         phr->u.c.an_log_value[0] = pC->u.vol.an_log[0];
363                         phr->u.c.an_log_value[1] = pC->u.vol.an_log[1];
364                 } else if (phm->u.c.attribute == HPI_VOLUME_MUTE) {
365                         if (pC->u.vol.flags & HPI_VOLUME_FLAG_HAS_MUTE) {
366                                 if (pC->u.vol.flags & HPI_VOLUME_FLAG_MUTED)
367                                         phr->u.c.param1 =
368                                                 HPI_BITMASK_ALL_CHANNELS;
369                                 else
370                                         phr->u.c.param1 = 0;
371                         } else {
372                                 phr->error =
373                                         HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
374                                 phr->u.c.param1 = 0;
375                         }
376                 } else {
377                         found = 0;
378                 }
379                 break;
380         case HPI_CONTROL_MULTIPLEXER:
381                 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
382                         phr->u.c.param1 = pC->u.mux.source_node_type;
383                         phr->u.c.param2 = pC->u.mux.source_node_index;
384                 } else {
385                         found = 0;
386                 }
387                 break;
388         case HPI_CONTROL_CHANNEL_MODE:
389                 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
390                         phr->u.c.param1 = pC->u.mode.mode;
391                 else
392                         found = 0;
393                 break;
394         case HPI_CONTROL_LEVEL:
395                 if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
396                         phr->u.c.an_log_value[0] = pC->u.level.an_log[0];
397                         phr->u.c.an_log_value[1] = pC->u.level.an_log[1];
398                 } else
399                         found = 0;
400                 break;
401         case HPI_CONTROL_TUNER:
402                 if (phm->u.c.attribute == HPI_TUNER_FREQ)
403                         phr->u.c.param1 = pC->u.tuner.freq_ink_hz;
404                 else if (phm->u.c.attribute == HPI_TUNER_BAND)
405                         phr->u.c.param1 = pC->u.tuner.band;
406                 else if (phm->u.c.attribute == HPI_TUNER_LEVEL_AVG)
407                         if (pC->u.tuner.s_level_avg ==
408                                 HPI_CACHE_INVALID_SHORT) {
409                                 phr->u.cu.tuner.s_level = 0;
410                                 phr->error =
411                                         HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
412                         } else
413                                 phr->u.cu.tuner.s_level =
414                                         pC->u.tuner.s_level_avg;
415                 else
416                         found = 0;
417                 break;
418         case HPI_CONTROL_AESEBU_RECEIVER:
419                 if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS)
420                         phr->u.c.param1 = pC->u.aes3rx.error_status;
421                 else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
422                         phr->u.c.param1 = pC->u.aes3rx.format;
423                 else
424                         found = 0;
425                 break;
426         case HPI_CONTROL_AESEBU_TRANSMITTER:
427                 if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
428                         phr->u.c.param1 = pC->u.aes3tx.format;
429                 else
430                         found = 0;
431                 break;
432         case HPI_CONTROL_TONEDETECTOR:
433                 if (phm->u.c.attribute == HPI_TONEDETECTOR_STATE)
434                         phr->u.c.param1 = pC->u.tone.state;
435                 else
436                         found = 0;
437                 break;
438         case HPI_CONTROL_SILENCEDETECTOR:
439                 if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) {
440                         phr->u.c.param1 = pC->u.silence.state;
441                 } else
442                         found = 0;
443                 break;
444         case HPI_CONTROL_MICROPHONE:
445                 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
446                         phr->u.c.param1 = pC->u.microphone.phantom_state;
447                 else
448                         found = 0;
449                 break;
450         case HPI_CONTROL_SAMPLECLOCK:
451                 if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
452                         phr->u.c.param1 = pC->u.clk.source;
453                 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) {
454                         if (pC->u.clk.source_index ==
455                                 HPI_CACHE_INVALID_UINT16) {
456                                 phr->u.c.param1 = 0;
457                                 phr->error =
458                                         HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
459                         } else
460                                 phr->u.c.param1 = pC->u.clk.source_index;
461                 } else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
462                         phr->u.c.param1 = pC->u.clk.sample_rate;
463                 else
464                         found = 0;
465                 break;
466         case HPI_CONTROL_PAD:{
467                         struct hpi_control_cache_pad *p_pad;
468                         p_pad = (struct hpi_control_cache_pad *)pI;
469
470                         if (!(p_pad->field_valid_flags & (1 <<
471                                                 HPI_CTL_ATTR_INDEX(phm->u.c.
472                                                         attribute)))) {
473                                 phr->error =
474                                         HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
475                                 break;
476                         }
477
478                         if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID)
479                                 phr->u.c.param1 = p_pad->pI;
480                         else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE)
481                                 phr->u.c.param1 = p_pad->pTY;
482                         else {
483                                 unsigned int index =
484                                         HPI_CTL_ATTR_INDEX(phm->u.c.
485                                         attribute) - 1;
486                                 unsigned int offset = phm->u.c.param1;
487                                 unsigned int pad_string_len, field_size;
488                                 char *pad_string;
489                                 unsigned int tocopy;
490
491                                 if (index > ARRAY_SIZE(pad_desc) - 1) {
492                                         phr->error =
493                                                 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
494                                         break;
495                                 }
496
497                                 pad_string =
498                                         ((char *)p_pad) +
499                                         pad_desc[index].offset;
500                                 field_size = pad_desc[index].field_size;
501                                 /* Ensure null terminator */
502                                 pad_string[field_size - 1] = 0;
503
504                                 pad_string_len = strlen(pad_string) + 1;
505
506                                 if (offset > pad_string_len) {
507                                         phr->error =
508                                                 HPI_ERROR_INVALID_CONTROL_VALUE;
509                                         break;
510                                 }
511
512                                 tocopy = pad_string_len - offset;
513                                 if (tocopy > sizeof(phr->u.cu.chars8.sz_data))
514                                         tocopy = sizeof(phr->u.cu.chars8.
515                                                 sz_data);
516
517                                 memcpy(phr->u.cu.chars8.sz_data,
518                                         &pad_string[offset], tocopy);
519
520                                 phr->u.cu.chars8.remaining_chars =
521                                         pad_string_len - offset - tocopy;
522                         }
523                 }
524                 break;
525         default:
526                 found = 0;
527                 break;
528         }
529
530         HPI_DEBUG_LOG(VERBOSE, "%s Adap %d, Ctl %d, Type %d, Attr %d\n",
531                 found ? "Cached" : "Uncached", phm->adapter_index,
532                 pI->control_index, pI->control_type, phm->u.c.attribute);
533
534         if (found)
535                 phr->size = response_size;
536
537         return found;
538 }
539
540 /** Updates the cache with Set values.
541
542 Only update if no error.
543 Volume and Level return the limited values in the response, so use these
544 Multiplexer does so use sent values
545 */
546 void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache,
547         struct hpi_message *phm, struct hpi_response *phr)
548 {
549         struct hpi_control_cache_single *pC;
550         struct hpi_control_cache_info *pI;
551
552         if (phr->error)
553                 return;
554
555         if (!find_control(phm->obj_index, p_cache, &pI)) {
556                 HPI_DEBUG_LOG(VERBOSE,
557                         "HPICMN find_control() failed for adap %d\n",
558                         phm->adapter_index);
559                 return;
560         }
561
562         /* pC is the default cached control strucure.
563            May be cast to something else in the following switch statement.
564          */
565         pC = (struct hpi_control_cache_single *)pI;
566
567         switch (pI->control_type) {
568         case HPI_CONTROL_VOLUME:
569                 if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
570                         pC->u.vol.an_log[0] = phr->u.c.an_log_value[0];
571                         pC->u.vol.an_log[1] = phr->u.c.an_log_value[1];
572                 } else if (phm->u.c.attribute == HPI_VOLUME_MUTE) {
573                         if (phm->u.c.param1)
574                                 pC->u.vol.flags |= HPI_VOLUME_FLAG_MUTED;
575                         else
576                                 pC->u.vol.flags &= ~HPI_VOLUME_FLAG_MUTED;
577                 }
578                 break;
579         case HPI_CONTROL_MULTIPLEXER:
580                 /* mux does not return its setting on Set command. */
581                 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
582                         pC->u.mux.source_node_type = (u16)phm->u.c.param1;
583                         pC->u.mux.source_node_index = (u16)phm->u.c.param2;
584                 }
585                 break;
586         case HPI_CONTROL_CHANNEL_MODE:
587                 /* mode does not return its setting on Set command. */
588                 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
589                         pC->u.mode.mode = (u16)phm->u.c.param1;
590                 break;
591         case HPI_CONTROL_LEVEL:
592                 if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
593                         pC->u.vol.an_log[0] = phr->u.c.an_log_value[0];
594                         pC->u.vol.an_log[1] = phr->u.c.an_log_value[1];
595                 }
596                 break;
597         case HPI_CONTROL_MICROPHONE:
598                 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
599                         pC->u.microphone.phantom_state = (u16)phm->u.c.param1;
600                 break;
601         case HPI_CONTROL_AESEBU_TRANSMITTER:
602                 if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
603                         pC->u.aes3tx.format = phm->u.c.param1;
604                 break;
605         case HPI_CONTROL_AESEBU_RECEIVER:
606                 if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
607                         pC->u.aes3rx.format = phm->u.c.param1;
608                 break;
609         case HPI_CONTROL_SAMPLECLOCK:
610                 if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
611                         pC->u.clk.source = (u16)phm->u.c.param1;
612                 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX)
613                         pC->u.clk.source_index = (u16)phm->u.c.param1;
614                 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
615                         pC->u.clk.sample_rate = phm->u.c.param1;
616                 break;
617         default:
618                 break;
619         }
620 }
621
622 /** Allocate control cache.
623
624 \return Cache pointer, or NULL if allocation fails.
625 */
626 struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count,
627         const u32 size_in_bytes, u8 *p_dsp_control_buffer)
628 {
629         struct hpi_control_cache *p_cache =
630                 kmalloc(sizeof(*p_cache), GFP_KERNEL);
631         if (!p_cache)
632                 return NULL;
633
634         p_cache->p_info =
635                 kmalloc(sizeof(*p_cache->p_info) * control_count, GFP_KERNEL);
636         if (!p_cache->p_info) {
637                 kfree(p_cache);
638                 return NULL;
639         }
640         memset(p_cache->p_info, 0, sizeof(*p_cache->p_info) * control_count);
641         p_cache->cache_size_in_bytes = size_in_bytes;
642         p_cache->control_count = control_count;
643         p_cache->p_cache = p_dsp_control_buffer;
644         p_cache->init = 0;
645         return p_cache;
646 }
647
648 void hpi_free_control_cache(struct hpi_control_cache *p_cache)
649 {
650         if (p_cache) {
651                 kfree(p_cache->p_info);
652                 kfree(p_cache);
653         }
654 }
655
656 static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
657 {
658         hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, 0);
659
660         switch (phm->function) {
661         case HPI_SUBSYS_OPEN:
662         case HPI_SUBSYS_CLOSE:
663         case HPI_SUBSYS_DRIVER_UNLOAD:
664                 break;
665         case HPI_SUBSYS_DRIVER_LOAD:
666                 wipe_adapter_list();
667                 hpios_alistlock_init(&adapters);
668                 break;
669         case HPI_SUBSYS_GET_ADAPTER:
670                 subsys_get_adapter(phm, phr);
671                 break;
672         case HPI_SUBSYS_GET_NUM_ADAPTERS:
673                 phr->u.s.num_adapters = adapters.gw_num_adapters;
674                 break;
675         case HPI_SUBSYS_CREATE_ADAPTER:
676                 break;
677         default:
678                 phr->error = HPI_ERROR_INVALID_FUNC;
679                 break;
680         }
681 }
682
683 void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr)
684 {
685         switch (phm->type) {
686         case HPI_TYPE_REQUEST:
687                 switch (phm->object) {
688                 case HPI_OBJ_SUBSYSTEM:
689                         subsys_message(phm, phr);
690                         break;
691                 }
692                 break;
693
694         default:
695                 phr->error = HPI_ERROR_INVALID_TYPE;
696                 break;
697         }
698 }