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 function %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].type) {
81 int a;
82 for (a = HPI_MAX_ADAPTERS - 1; a >= 0; a--) {
83 if (!adapters.adapter[a].type) {
84 HPI_DEBUG_LOG(WARNING,
85 "ASI%X duplicate index %d moved to %d\n",
86 pao->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->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].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->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].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].type;
178 } else {
179 phr->u.s.adapter_index = 0;
180 phr->u.s.adapter_type = 0;
181 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
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 u16 control_index = info->control_index;
210
211 if (control_index >= pC->control_count) {
212 HPI_DEBUG_LOG(INFO,
213 "adap %d control index %d out of range, cache not ready?\n",
214 pC->adap_idx, control_index);
215 return 0;
216 }
217
218 if (!info->size_in32bit_words) {
219 if (!i) {
220 HPI_DEBUG_LOG(INFO,
221 "adap %d cache not ready?\n",
222 pC->adap_idx);
223 return 0;
224 }
225
226
227
228
229 HPI_DEBUG_LOG(ERROR,
230 "adap %d zero size cache entry %d\n",
231 pC->adap_idx, i);
232 break;
233 }
234
235 if (info->control_type) {
236 pC->p_info[control_index] = info;
237 cached++;
238 } else {
239 pC->p_info[control_index] = NULL;
240 }
241
242 byte_count += info->size_in32bit_words * 4;
243
244 HPI_DEBUG_LOG(VERBOSE,
245 "cached %d, pinfo %p index %d type %d size %d\n",
246 cached, pC->p_info[info->control_index],
247 info->control_index, info->control_type,
248 info->size_in32bit_words);
249
250
251
252
253
254 if (byte_count >= pC->cache_size_in_bytes)
255 break;
256
257 if (info->control_index == pC->control_count - 1)
258 break;
259 }
260
261 if (byte_count != pC->cache_size_in_bytes)
262 HPI_DEBUG_LOG(WARNING,
263 "adap %d bytecount %d != cache size %d\n",
264 pC->adap_idx, byte_count,
265 pC->cache_size_in_bytes);
266 else
267 HPI_DEBUG_LOG(DEBUG,
268 "adap %d cache good, bytecount == cache size = %d\n",
269 pC->adap_idx, byte_count);
270
271 pC->init = (u16)cached;
272 }
273 return pC->init;
274}
275
276
277
278static short find_control(u16 control_index,
279 struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI)
280{
281 if (!control_cache_alloc_check(p_cache)) {
282 HPI_DEBUG_LOG(VERBOSE,
283 "control_cache_alloc_check() failed %d\n",
284 control_index);
285 return 0;
286 }
287
288 *pI = p_cache->p_info[control_index];
289 if (!*pI) {
290 HPI_DEBUG_LOG(VERBOSE, "Uncached Control %d\n",
291 control_index);
292 return 0;
293 } else {
294 HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n",
295 (*pI)->control_type);
296 }
297 return 1;
298}
299
300
301#define HPICMN_PAD_OFS_AND_SIZE(m) {\
302 offsetof(struct hpi_control_cache_pad, m), \
303 sizeof(((struct hpi_control_cache_pad *)(NULL))->m) }
304
305struct pad_ofs_size {
306 unsigned int offset;
307 unsigned int field_size;
308};
309
310static const struct pad_ofs_size pad_desc[] = {
311 HPICMN_PAD_OFS_AND_SIZE(c_channel),
312 HPICMN_PAD_OFS_AND_SIZE(c_artist),
313 HPICMN_PAD_OFS_AND_SIZE(c_title),
314 HPICMN_PAD_OFS_AND_SIZE(c_comment),
315};
316
317
318
319
320short hpi_check_control_cache_single(struct hpi_control_cache_single *pC,
321 struct hpi_message *phm, struct hpi_response *phr)
322{
323 size_t response_size;
324 short found = 1;
325
326
327 response_size =
328 sizeof(struct hpi_response_header) +
329 sizeof(struct hpi_control_res);
330
331 switch (pC->u.i.control_type) {
332
333 case HPI_CONTROL_METER:
334 if (phm->u.c.attribute == HPI_METER_PEAK) {
335 phr->u.c.an_log_value[0] = pC->u.meter.an_log_peak[0];
336 phr->u.c.an_log_value[1] = pC->u.meter.an_log_peak[1];
337 } else if (phm->u.c.attribute == HPI_METER_RMS) {
338 if (pC->u.meter.an_logRMS[0] ==
339 HPI_CACHE_INVALID_SHORT) {
340 phr->error =
341 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
342 phr->u.c.an_log_value[0] = HPI_METER_MINIMUM;
343 phr->u.c.an_log_value[1] = HPI_METER_MINIMUM;
344 } else {
345 phr->u.c.an_log_value[0] =
346 pC->u.meter.an_logRMS[0];
347 phr->u.c.an_log_value[1] =
348 pC->u.meter.an_logRMS[1];
349 }
350 } else
351 found = 0;
352 break;
353 case HPI_CONTROL_VOLUME:
354 if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
355 phr->u.c.an_log_value[0] = pC->u.vol.an_log[0];
356 phr->u.c.an_log_value[1] = pC->u.vol.an_log[1];
357 } else if (phm->u.c.attribute == HPI_VOLUME_MUTE) {
358 if (pC->u.vol.flags & HPI_VOLUME_FLAG_HAS_MUTE) {
359 if (pC->u.vol.flags & HPI_VOLUME_FLAG_MUTED)
360 phr->u.c.param1 =
361 HPI_BITMASK_ALL_CHANNELS;
362 else
363 phr->u.c.param1 = 0;
364 } else {
365 phr->error =
366 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
367 phr->u.c.param1 = 0;
368 }
369 } else {
370 found = 0;
371 }
372 break;
373 case HPI_CONTROL_MULTIPLEXER:
374 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
375 phr->u.c.param1 = pC->u.mux.source_node_type;
376 phr->u.c.param2 = pC->u.mux.source_node_index;
377 } else {
378 found = 0;
379 }
380 break;
381 case HPI_CONTROL_CHANNEL_MODE:
382 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
383 phr->u.c.param1 = pC->u.mode.mode;
384 else
385 found = 0;
386 break;
387 case HPI_CONTROL_LEVEL:
388 if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
389 phr->u.c.an_log_value[0] = pC->u.level.an_log[0];
390 phr->u.c.an_log_value[1] = pC->u.level.an_log[1];
391 } else
392 found = 0;
393 break;
394 case HPI_CONTROL_TUNER:
395 if (phm->u.c.attribute == HPI_TUNER_FREQ)
396 phr->u.c.param1 = pC->u.tuner.freq_ink_hz;
397 else if (phm->u.c.attribute == HPI_TUNER_BAND)
398 phr->u.c.param1 = pC->u.tuner.band;
399 else if (phm->u.c.attribute == HPI_TUNER_LEVEL_AVG)
400 if (pC->u.tuner.s_level_avg ==
401 HPI_CACHE_INVALID_SHORT) {
402 phr->u.cu.tuner.s_level = 0;
403 phr->error =
404 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
405 } else
406 phr->u.cu.tuner.s_level =
407 pC->u.tuner.s_level_avg;
408 else
409 found = 0;
410 break;
411 case HPI_CONTROL_AESEBU_RECEIVER:
412 if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS)
413 phr->u.c.param1 = pC->u.aes3rx.error_status;
414 else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
415 phr->u.c.param1 = pC->u.aes3rx.format;
416 else
417 found = 0;
418 break;
419 case HPI_CONTROL_AESEBU_TRANSMITTER:
420 if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
421 phr->u.c.param1 = pC->u.aes3tx.format;
422 else
423 found = 0;
424 break;
425 case HPI_CONTROL_TONEDETECTOR:
426 if (phm->u.c.attribute == HPI_TONEDETECTOR_STATE)
427 phr->u.c.param1 = pC->u.tone.state;
428 else
429 found = 0;
430 break;
431 case HPI_CONTROL_SILENCEDETECTOR:
432 if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) {
433 phr->u.c.param1 = pC->u.silence.state;
434 } else
435 found = 0;
436 break;
437 case HPI_CONTROL_MICROPHONE:
438 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
439 phr->u.c.param1 = pC->u.microphone.phantom_state;
440 else
441 found = 0;
442 break;
443 case HPI_CONTROL_SAMPLECLOCK:
444 if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
445 phr->u.c.param1 = pC->u.clk.source;
446 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) {
447 if (pC->u.clk.source_index ==
448 HPI_CACHE_INVALID_UINT16) {
449 phr->u.c.param1 = 0;
450 phr->error =
451 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
452 } else
453 phr->u.c.param1 = pC->u.clk.source_index;
454 } else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
455 phr->u.c.param1 = pC->u.clk.sample_rate;
456 else
457 found = 0;
458 break;
459 case HPI_CONTROL_PAD:{
460 struct hpi_control_cache_pad *p_pad;
461 p_pad = (struct hpi_control_cache_pad *)pC;
462
463 if (!(p_pad->field_valid_flags & (1 <<
464 HPI_CTL_ATTR_INDEX(phm->u.c.
465 attribute)))) {
466 phr->error =
467 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
468 break;
469 }
470
471 if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID)
472 phr->u.c.param1 = p_pad->pI;
473 else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE)
474 phr->u.c.param1 = p_pad->pTY;
475 else {
476 unsigned int index =
477 HPI_CTL_ATTR_INDEX(phm->u.c.
478 attribute) - 1;
479 unsigned int offset = phm->u.c.param1;
480 unsigned int pad_string_len, field_size;
481 char *pad_string;
482 unsigned int tocopy;
483
484 if (index > ARRAY_SIZE(pad_desc) - 1) {
485 phr->error =
486 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
487 break;
488 }
489
490 pad_string =
491 ((char *)p_pad) +
492 pad_desc[index].offset;
493 field_size = pad_desc[index].field_size;
494
495 pad_string[field_size - 1] = 0;
496
497 pad_string_len = strlen(pad_string) + 1;
498
499 if (offset > pad_string_len) {
500 phr->error =
501 HPI_ERROR_INVALID_CONTROL_VALUE;
502 break;
503 }
504
505 tocopy = pad_string_len - offset;
506 if (tocopy > sizeof(phr->u.cu.chars8.sz_data))
507 tocopy = sizeof(phr->u.cu.chars8.
508 sz_data);
509
510 memcpy(phr->u.cu.chars8.sz_data,
511 &pad_string[offset], tocopy);
512
513 phr->u.cu.chars8.remaining_chars =
514 pad_string_len - offset - tocopy;
515 }
516 }
517 break;
518 default:
519 found = 0;
520 break;
521 }
522
523 HPI_DEBUG_LOG(VERBOSE, "%s Adap %d, Ctl %d, Type %d, Attr %d\n",
524 found ? "Cached" : "Uncached", phm->adapter_index,
525 pC->u.i.control_index, pC->u.i.control_type,
526 phm->u.c.attribute);
527
528 if (found) {
529 phr->size = (u16)response_size;
530 phr->type = HPI_TYPE_RESPONSE;
531 phr->object = phm->object;
532 phr->function = phm->function;
533 }
534
535 return found;
536}
537
538short hpi_check_control_cache(struct hpi_control_cache *p_cache,
539 struct hpi_message *phm, struct hpi_response *phr)
540{
541 struct hpi_control_cache_info *pI;
542
543 if (!find_control(phm->obj_index, p_cache, &pI)) {
544 HPI_DEBUG_LOG(VERBOSE,
545 "HPICMN find_control() failed for adap %d\n",
546 phm->adapter_index);
547 return 0;
548 }
549
550 phr->error = 0;
551 phr->specific_error = 0;
552 phr->version = 0;
553
554 return hpi_check_control_cache_single((struct hpi_control_cache_single
555 *)pI, phm, phr);
556}
557
558
559
560
561
562
563
564void hpi_cmn_control_cache_sync_to_msg_single(struct hpi_control_cache_single
565 *pC, struct hpi_message *phm, struct hpi_response *phr)
566{
567 switch (pC->u.i.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
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
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
622void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache,
623 struct hpi_message *phm, struct hpi_response *phr)
624{
625 struct hpi_control_cache_single *pC;
626 struct hpi_control_cache_info *pI;
627
628 if (phr->error)
629 return;
630
631 if (!find_control(phm->obj_index, p_cache, &pI)) {
632 HPI_DEBUG_LOG(VERBOSE,
633 "HPICMN find_control() failed for adap %d\n",
634 phm->adapter_index);
635 return;
636 }
637
638
639
640
641 pC = (struct hpi_control_cache_single *)pI;
642
643 hpi_cmn_control_cache_sync_to_msg_single(pC, phm, phr);
644}
645
646
647
648
649
650struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count,
651 const u32 size_in_bytes, u8 *p_dsp_control_buffer)
652{
653 struct hpi_control_cache *p_cache =
654 kmalloc(sizeof(*p_cache), GFP_KERNEL);
655 if (!p_cache)
656 return NULL;
657
658 p_cache->p_info =
659 kcalloc(control_count, sizeof(*p_cache->p_info), GFP_KERNEL);
660 if (!p_cache->p_info) {
661 kfree(p_cache);
662 return NULL;
663 }
664
665 p_cache->cache_size_in_bytes = size_in_bytes;
666 p_cache->control_count = control_count;
667 p_cache->p_cache = p_dsp_control_buffer;
668 p_cache->init = 0;
669 return p_cache;
670}
671
672void hpi_free_control_cache(struct hpi_control_cache *p_cache)
673{
674 if (p_cache) {
675 kfree(p_cache->p_info);
676 kfree(p_cache);
677 }
678}
679
680static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
681{
682 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, 0);
683
684 switch (phm->function) {
685 case HPI_SUBSYS_OPEN:
686 case HPI_SUBSYS_CLOSE:
687 case HPI_SUBSYS_DRIVER_UNLOAD:
688 break;
689 case HPI_SUBSYS_DRIVER_LOAD:
690 wipe_adapter_list();
691 hpios_alistlock_init(&adapters);
692 break;
693 case HPI_SUBSYS_GET_ADAPTER:
694 subsys_get_adapter(phm, phr);
695 break;
696 case HPI_SUBSYS_GET_NUM_ADAPTERS:
697 phr->u.s.num_adapters = adapters.gw_num_adapters;
698 break;
699 case HPI_SUBSYS_CREATE_ADAPTER:
700 break;
701 default:
702 phr->error = HPI_ERROR_INVALID_FUNC;
703 break;
704 }
705}
706
707void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr)
708{
709 switch (phm->type) {
710 case HPI_TYPE_REQUEST:
711 switch (phm->object) {
712 case HPI_OBJ_SUBSYSTEM:
713 subsys_message(phm, phr);
714 break;
715 }
716 break;
717
718 default:
719 phr->error = HPI_ERROR_INVALID_TYPE;
720 break;
721 }
722}
723