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