1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
43
44
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
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
121
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
138
139
140 return pao;
141 } else {
142
143
144
145
146 return NULL;
147 }
148}
149
150
151
152
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
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
218
219
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
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
242
243
244
245 if (byte_count >= pC->cache_size_in_bytes)
246 break;
247
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
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
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),
303 HPICMN_PAD_OFS_AND_SIZE(c_artist),
304 HPICMN_PAD_OFS_AND_SIZE(c_title),
305 HPICMN_PAD_OFS_AND_SIZE(c_comment),
306};
307
308
309
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
329
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
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
539
540
541
542
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
561
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
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
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