ALSA: asihpi - Increase debug response buffer size.
[deliverable/linux.git] / sound / pci / asihpi / hpicmn.c
CommitLineData
719f82d3
EB
1/******************************************************************************
2
3 AudioScience HPI driver
40818b62 4 Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
719f82d3
EB
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) {
938c565a 60 HPI_DEBUG_LOG(ERROR, "header function %d invalid\n",
1528fbb5 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) {
d6f1c1c3
EB
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;
719f82d3
EB
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:
3285ea10 101 hpios_alistlock_unlock(&adapters);
719f82d3
EB
102 return retval;
103}
104
105void hpi_delete_adapter(struct hpi_adapter_obj *pao)
106{
3285ea10
EB
107 if (!pao->adapter_type) {
108 HPI_DEBUG_LOG(ERROR, "removing null adapter?\n");
109 return;
110 }
719f82d3
EB
111
112 hpios_alistlock_lock(&adapters);
3285ea10
EB
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);
719f82d3
EB
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) {
1528fbb5 129 HPI_DEBUG_LOG(VERBOSE, "find_adapter invalid index %d\n",
719f82d3
EB
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**/
3285ea10 155static void wipe_adapter_list(void)
719f82d3
EB
156{
157 memset(&adapters, 0, sizeof(adapters));
158}
159
3285ea10
EB
160static void subsys_get_adapter(struct hpi_message *phm,
161 struct hpi_response *phr)
719f82d3 162{
3285ea10
EB
163 int count = phm->obj_index;
164 u16 index = 0;
719f82d3 165
3285ea10
EB
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) {
4704998e 169 if (!count)
3285ea10
EB
170 break;
171 count--;
719f82d3 172 }
719f82d3
EB
173 }
174
3285ea10
EB
175 if (index < HPI_MAX_ADAPTERS) {
176 phr->u.s.adapter_index = adapters.adapter[index].index;
2f918a64 177 phr->u.s.adapter_type = adapters.adapter[index].adapter_type;
3285ea10
EB
178 } else {
179 phr->u.s.adapter_index = 0;
2f918a64 180 phr->u.s.adapter_type = 0;
3285ea10
EB
181 phr->error = HPI_ERROR_BAD_ADAPTER_NUMBER;
182 }
719f82d3
EB
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;
719f82d3 191
3285ea10
EB
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",
719f82d3
EB
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 *)
3285ea10
EB
208 &p_master_cache[byte_count];
209
210 if (!info->size_in32bit_words) {
4704998e 211 if (!i) {
ffdb5787
EB
212 HPI_DEBUG_LOG(INFO,
213 "adap %d cache not ready?\n",
214 pC->adap_idx);
215 return 0;
216 }
1528fbb5
EB
217 /* The cache is invalid.
218 * Minimum valid entry size is
219 * sizeof(struct hpi_control_cache_info)
220 */
3285ea10 221 HPI_DEBUG_LOG(ERROR,
ffdb5787
EB
222 "adap %d zero size cache entry %d\n",
223 pC->adap_idx, i);
3285ea10
EB
224 break;
225 }
719f82d3
EB
226
227 if (info->control_type) {
3285ea10 228 pC->p_info[info->control_index] = info;
719f82d3 229 cached++;
42258dab 230 } else { /* dummy cache entry */
3285ea10 231 pC->p_info[info->control_index] = NULL;
42258dab 232 }
719f82d3 233
3285ea10 234 byte_count += info->size_in32bit_words * 4;
719f82d3
EB
235
236 HPI_DEBUG_LOG(VERBOSE,
3285ea10
EB
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
1528fbb5
EB
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 */
3285ea10
EB
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;
719f82d3 251 }
3285ea10
EB
252
253 if (byte_count != pC->cache_size_in_bytes)
254 HPI_DEBUG_LOG(WARNING,
1528fbb5 255 "adap %d bytecount %d != cache size %d\n",
ffdb5787 256 pC->adap_idx, byte_count,
3285ea10
EB
257 pC->cache_size_in_bytes);
258 else
259 HPI_DEBUG_LOG(DEBUG,
1528fbb5 260 "adap %d cache good, bytecount == cache size = %d\n",
ffdb5787 261 pC->adap_idx, byte_count);
3285ea10 262
1528fbb5 263 pC->init = (u16)cached;
719f82d3
EB
264 }
265 return pC->init;
266}
267
268/** Find a control.
269*/
3285ea10
EB
270static short find_control(u16 control_index,
271 struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI)
719f82d3 272{
719f82d3
EB
273 if (!control_cache_alloc_check(p_cache)) {
274 HPI_DEBUG_LOG(VERBOSE,
3285ea10
EB
275 "control_cache_alloc_check() failed %d\n",
276 control_index);
719f82d3
EB
277 return 0;
278 }
279
3285ea10 280 *pI = p_cache->p_info[control_index];
719f82d3 281 if (!*pI) {
3285ea10
EB
282 HPI_DEBUG_LOG(VERBOSE, "Uncached Control %d\n",
283 control_index);
719f82d3
EB
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
719f82d3
EB
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
297struct pad_ofs_size {
298 unsigned int offset;
299 unsigned int field_size;
300};
301
42258dab 302static const struct pad_ofs_size pad_desc[] = {
719f82d3
EB
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 */
312short hpi_check_control_cache(struct hpi_control_cache *p_cache,
313 struct hpi_message *phm, struct hpi_response *phr)
314{
315 short found = 1;
719f82d3
EB
316 struct hpi_control_cache_info *pI;
317 struct hpi_control_cache_single *pC;
3d0591ee 318 size_t response_size;
3285ea10
EB
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);
719f82d3 323 return 0;
3285ea10 324 }
719f82d3
EB
325
326 phr->error = 0;
327
c6c2c9ab
EB
328 /* set the default response size */
329 response_size =
330 sizeof(struct hpi_response_header) +
331 sizeof(struct hpi_control_res);
332
719f82d3
EB
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;
719f82d3
EB
337
338 switch (pI->control_type) {
339
340 case HPI_CONTROL_METER:
341 if (phm->u.c.attribute == HPI_METER_PEAK) {
3285ea10
EB
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];
719f82d3 344 } else if (phm->u.c.attribute == HPI_METER_RMS) {
3285ea10
EB
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 }
719f82d3
EB
357 } else
358 found = 0;
359 break;
360 case HPI_CONTROL_VOLUME:
361 if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
3285ea10
EB
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];
fc3a3990
EB
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 {
719f82d3 377 found = 0;
fc3a3990 378 }
719f82d3
EB
379 break;
380 case HPI_CONTROL_MULTIPLEXER:
381 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
3285ea10
EB
382 phr->u.c.param1 = pC->u.mux.source_node_type;
383 phr->u.c.param2 = pC->u.mux.source_node_index;
719f82d3
EB
384 } else {
385 found = 0;
386 }
387 break;
388 case HPI_CONTROL_CHANNEL_MODE:
389 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
3285ea10 390 phr->u.c.param1 = pC->u.mode.mode;
719f82d3
EB
391 else
392 found = 0;
393 break;
394 case HPI_CONTROL_LEVEL:
395 if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
3285ea10
EB
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];
719f82d3
EB
398 } else
399 found = 0;
400 break;
401 case HPI_CONTROL_TUNER:
3ee317fe 402 if (phm->u.c.attribute == HPI_TUNER_FREQ)
3285ea10 403 phr->u.c.param1 = pC->u.tuner.freq_ink_hz;
3ee317fe 404 else if (phm->u.c.attribute == HPI_TUNER_BAND)
3285ea10
EB
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;
36ed8bdd
EB
410 phr->error =
411 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
412 } else
3285ea10
EB
413 phr->u.cu.tuner.s_level =
414 pC->u.tuner.s_level_avg;
3ee317fe
EB
415 else
416 found = 0;
719f82d3
EB
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)
3285ea10 422 phr->u.c.param1 = pC->u.aes3rx.format;
719f82d3
EB
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;
719f82d3
EB
441 } else
442 found = 0;
443 break;
444 case HPI_CONTROL_MICROPHONE:
445 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
3285ea10 446 phr->u.c.param1 = pC->u.microphone.phantom_state;
719f82d3
EB
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 ==
3285ea10 455 HPI_CACHE_INVALID_UINT16) {
719f82d3 456 phr->u.c.param1 = 0;
36ed8bdd
EB
457 phr->error =
458 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
719f82d3
EB
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;
3285ea10
EB
466 case HPI_CONTROL_PAD:{
467 struct hpi_control_cache_pad *p_pad;
468 p_pad = (struct hpi_control_cache_pad *)pI;
719f82d3 469
3285ea10
EB
470 if (!(p_pad->field_valid_flags & (1 <<
471 HPI_CTL_ATTR_INDEX(phm->u.c.
472 attribute)))) {
719f82d3
EB
473 phr->error =
474 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
475 break;
476 }
477
3285ea10
EB
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;
719f82d3 522 }
719f82d3
EB
523 }
524 break;
525 default:
526 found = 0;
527 break;
528 }
529
3285ea10
EB
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);
719f82d3
EB
533
534 if (found)
3d0591ee 535 phr->size = (u16)response_size;
719f82d3
EB
536
537 return found;
538}
539
540/** Updates the cache with Set values.
541
542Only update if no error.
543Volume and Level return the limited values in the response, so use these
544Multiplexer does so use sent values
545*/
3285ea10 546void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache,
719f82d3
EB
547 struct hpi_message *phm, struct hpi_response *phr)
548{
719f82d3
EB
549 struct hpi_control_cache_single *pC;
550 struct hpi_control_cache_info *pI;
551
3ee317fe
EB
552 if (phr->error)
553 return;
554
3285ea10
EB
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);
719f82d3 559 return;
3285ea10 560 }
719f82d3
EB
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) {
3285ea10
EB
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];
fc3a3990
EB
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;
719f82d3
EB
577 }
578 break;
579 case HPI_CONTROL_MULTIPLEXER:
580 /* mux does not return its setting on Set command. */
719f82d3 581 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
3285ea10
EB
582 pC->u.mux.source_node_type = (u16)phm->u.c.param1;
583 pC->u.mux.source_node_index = (u16)phm->u.c.param2;
719f82d3
EB
584 }
585 break;
586 case HPI_CONTROL_CHANNEL_MODE:
587 /* mode does not return its setting on Set command. */
719f82d3 588 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
3285ea10 589 pC->u.mode.mode = (u16)phm->u.c.param1;
719f82d3
EB
590 break;
591 case HPI_CONTROL_LEVEL:
592 if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
3285ea10
EB
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];
719f82d3
EB
595 }
596 break;
597 case HPI_CONTROL_MICROPHONE:
598 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
3285ea10 599 pC->u.microphone.phantom_state = (u16)phm->u.c.param1;
719f82d3
EB
600 break;
601 case HPI_CONTROL_AESEBU_TRANSMITTER:
719f82d3
EB
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:
719f82d3 606 if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
3285ea10 607 pC->u.aes3rx.format = phm->u.c.param1;
719f82d3
EB
608 break;
609 case HPI_CONTROL_SAMPLECLOCK:
719f82d3
EB
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
42258dab
EB
622/** Allocate control cache.
623
624\return Cache pointer, or NULL if allocation fails.
625*/
4704998e
EB
626struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count,
627 const u32 size_in_bytes, u8 *p_dsp_control_buffer)
719f82d3
EB
628{
629 struct hpi_control_cache *p_cache =
630 kmalloc(sizeof(*p_cache), GFP_KERNEL);
fd0977d0
JJ
631 if (!p_cache)
632 return NULL;
4704998e 633
6d2d4313 634 p_cache->p_info = kcalloc(control_count, sizeof(*p_cache->p_info),
67ada836 635 GFP_KERNEL);
fd0977d0
JJ
636 if (!p_cache->p_info) {
637 kfree(p_cache);
638 return NULL;
639 }
719f82d3 640 p_cache->cache_size_in_bytes = size_in_bytes;
4704998e
EB
641 p_cache->control_count = control_count;
642 p_cache->p_cache = p_dsp_control_buffer;
719f82d3 643 p_cache->init = 0;
719f82d3
EB
644 return p_cache;
645}
646
647void hpi_free_control_cache(struct hpi_control_cache *p_cache)
648{
3285ea10 649 if (p_cache) {
719f82d3 650 kfree(p_cache->p_info);
719f82d3
EB
651 kfree(p_cache);
652 }
653}
654
655static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
656{
3285ea10 657 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, 0);
719f82d3
EB
658
659 switch (phm->function) {
660 case HPI_SUBSYS_OPEN:
661 case HPI_SUBSYS_CLOSE:
662 case HPI_SUBSYS_DRIVER_UNLOAD:
719f82d3
EB
663 break;
664 case HPI_SUBSYS_DRIVER_LOAD:
665 wipe_adapter_list();
666 hpios_alistlock_init(&adapters);
719f82d3 667 break;
3285ea10
EB
668 case HPI_SUBSYS_GET_ADAPTER:
669 subsys_get_adapter(phm, phr);
670 break;
671 case HPI_SUBSYS_GET_NUM_ADAPTERS:
672 phr->u.s.num_adapters = adapters.gw_num_adapters;
719f82d3
EB
673 break;
674 case HPI_SUBSYS_CREATE_ADAPTER:
719f82d3
EB
675 break;
676 default:
677 phr->error = HPI_ERROR_INVALID_FUNC;
678 break;
679 }
680}
681
682void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr)
683{
684 switch (phm->type) {
82b5774f 685 case HPI_TYPE_REQUEST:
719f82d3
EB
686 switch (phm->object) {
687 case HPI_OBJ_SUBSYSTEM:
688 subsys_message(phm, phr);
689 break;
690 }
691 break;
692
693 default:
694 phr->error = HPI_ERROR_INVALID_TYPE;
695 break;
696 }
697}
This page took 0.105495 seconds and 5 git commands to generate.