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 "hpicmn.h"
30
31struct hpi_adapters_list {
32 struct hpios_spinlock list_lock;
33 struct hpi_adapter_obj adapter[HPI_MAX_ADAPTERS];
34 u16 gw_num_adapters;
35};
36
37static struct hpi_adapters_list adapters;
38
39
40
41
42
43
44u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr)
45{
46 u16 error = 0;
47
48 if ((phr->type != HPI_TYPE_RESPONSE)
49 || (phr->object != phm->object)
50 || (phr->function != phm->function))
51 error = HPI_ERROR_INVALID_RESPONSE;
52
53 return error;
54}
55
56u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
57{
58 u16 retval = 0;
59
60
61 hpios_alistlock_lock(&adapters);
62
63 if (pao->index >= HPI_MAX_ADAPTERS) {
64 retval = HPI_ERROR_BAD_ADAPTER_NUMBER;
65 goto unlock;
66 }
67
68 if (adapters.adapter[pao->index].adapter_type) {
69 {
70 retval = HPI_DUPLICATE_ADAPTER_NUMBER;
71 goto unlock;
72 }
73 }
74 adapters.adapter[pao->index] = *pao;
75 hpios_dsplock_init(&adapters.adapter[pao->index]);
76 adapters.gw_num_adapters++;
77
78unlock:
79 hpios_alistlock_un_lock(&adapters);
80 return retval;
81}
82
83void hpi_delete_adapter(struct hpi_adapter_obj *pao)
84{
85 memset(pao, 0, sizeof(struct hpi_adapter_obj));
86
87 hpios_alistlock_lock(&adapters);
88 adapters.gw_num_adapters--;
89 hpios_alistlock_un_lock(&adapters);
90}
91
92
93
94
95
96
97struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index)
98{
99 struct hpi_adapter_obj *pao = NULL;
100
101 if (adapter_index >= HPI_MAX_ADAPTERS) {
102 HPI_DEBUG_LOG(VERBOSE, "find_adapter invalid index %d ",
103 adapter_index);
104 return NULL;
105 }
106
107 pao = &adapters.adapter[adapter_index];
108 if (pao->adapter_type != 0) {
109
110
111
112
113 return pao;
114 } else {
115
116
117
118
119 return NULL;
120 }
121}
122
123
124
125
126
127
128static void wipe_adapter_list(void
129 )
130{
131 memset(&adapters, 0, sizeof(adapters));
132}
133
134
135
136
137
138
139static void subsys_get_adapters(struct hpi_response *phr)
140{
141
142
143
144
145
146
147
148
149
150
151
152
153
154 short i;
155 struct hpi_adapter_obj *pao = NULL;
156
157 HPI_DEBUG_LOG(VERBOSE, "subsys_get_adapters\n");
158
159
160
161 for (i = 0; i < adapters.gw_num_adapters; i++) {
162 pao = &adapters.adapter[i];
163 if (phr->u.s.aw_adapter_list[pao->index] != 0) {
164 phr->error = HPI_DUPLICATE_ADAPTER_NUMBER;
165 phr->specific_error = pao->index;
166 return;
167 }
168 phr->u.s.aw_adapter_list[pao->index] = pao->adapter_type;
169 }
170
171 phr->u.s.num_adapters = adapters.gw_num_adapters;
172 phr->error = 0;
173}
174
175static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
176{
177 unsigned int i;
178 int cached = 0;
179 if (!pC)
180 return 0;
181 if ((!pC->init) && (pC->p_cache != NULL) && (pC->control_count)
182 && (pC->cache_size_in_bytes)
183 ) {
184 u32 *p_master_cache;
185 pC->init = 1;
186
187 p_master_cache = (u32 *)pC->p_cache;
188 HPI_DEBUG_LOG(VERBOSE, "check %d controls\n",
189 pC->control_count);
190 for (i = 0; i < pC->control_count; i++) {
191 struct hpi_control_cache_info *info =
192 (struct hpi_control_cache_info *)
193 p_master_cache;
194
195 if (info->control_type) {
196 pC->p_info[i] = info;
197 cached++;
198 } else
199 pC->p_info[i] = NULL;
200
201 if (info->size_in32bit_words)
202 p_master_cache += info->size_in32bit_words;
203 else
204 p_master_cache +=
205 sizeof(struct
206 hpi_control_cache_single) /
207 sizeof(u32);
208
209 HPI_DEBUG_LOG(VERBOSE,
210 "cached %d, pinfo %p index %d type %d\n",
211 cached, pC->p_info[i], info->control_index,
212 info->control_type);
213 }
214
215
216
217 if (!cached)
218 pC->init = 0;
219 }
220 return pC->init;
221}
222
223
224
225static short find_control(struct hpi_message *phm,
226 struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI,
227 u16 *pw_control_index)
228{
229 *pw_control_index = phm->obj_index;
230
231 if (!control_cache_alloc_check(p_cache)) {
232 HPI_DEBUG_LOG(VERBOSE,
233 "control_cache_alloc_check() failed. adap%d ci%d\n",
234 phm->adapter_index, *pw_control_index);
235 return 0;
236 }
237
238 *pI = p_cache->p_info[*pw_control_index];
239 if (!*pI) {
240 HPI_DEBUG_LOG(VERBOSE, "uncached adap %d, control %d\n",
241 phm->adapter_index, *pw_control_index);
242 return 0;
243 } else {
244 HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n",
245 (*pI)->control_type);
246 }
247 return 1;
248}
249
250
251
252short hpi_check_buffer_mapping(struct hpi_control_cache *p_cache,
253 struct hpi_message *phm, void **p, unsigned int *pN)
254{
255 *pN = 0;
256 *p = NULL;
257 if ((phm->function == HPI_CONTROL_GET_STATE)
258 && (phm->object == HPI_OBJ_CONTROLEX)
259 ) {
260 u16 control_index;
261 struct hpi_control_cache_info *pI;
262
263 if (!find_control(phm, p_cache, &pI, &control_index))
264 return 0;
265 }
266 return 0;
267}
268
269
270#define HPICMN_PAD_OFS_AND_SIZE(m) {\
271 offsetof(struct hpi_control_cache_pad, m), \
272 sizeof(((struct hpi_control_cache_pad *)(NULL))->m) }
273
274struct pad_ofs_size {
275 unsigned int offset;
276 unsigned int field_size;
277};
278
279static struct pad_ofs_size pad_desc[] = {
280 HPICMN_PAD_OFS_AND_SIZE(c_channel),
281 HPICMN_PAD_OFS_AND_SIZE(c_artist),
282 HPICMN_PAD_OFS_AND_SIZE(c_title),
283 HPICMN_PAD_OFS_AND_SIZE(c_comment),
284};
285
286
287
288
289short hpi_check_control_cache(struct hpi_control_cache *p_cache,
290 struct hpi_message *phm, struct hpi_response *phr)
291{
292 short found = 1;
293 u16 control_index;
294 struct hpi_control_cache_info *pI;
295 struct hpi_control_cache_single *pC;
296 struct hpi_control_cache_pad *p_pad;
297
298 if (!find_control(phm, p_cache, &pI, &control_index))
299 return 0;
300
301 phr->error = 0;
302
303
304
305
306 pC = (struct hpi_control_cache_single *)pI;
307 p_pad = (struct hpi_control_cache_pad *)pI;
308
309 switch (pI->control_type) {
310
311 case HPI_CONTROL_METER:
312 if (phm->u.c.attribute == HPI_METER_PEAK) {
313 phr->u.c.an_log_value[0] = pC->u.p.an_log_peak[0];
314 phr->u.c.an_log_value[1] = pC->u.p.an_log_peak[1];
315 } else if (phm->u.c.attribute == HPI_METER_RMS) {
316 phr->u.c.an_log_value[0] = pC->u.p.an_logRMS[0];
317 phr->u.c.an_log_value[1] = pC->u.p.an_logRMS[1];
318 } else
319 found = 0;
320 break;
321 case HPI_CONTROL_VOLUME:
322 if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
323 phr->u.c.an_log_value[0] = pC->u.v.an_log[0];
324 phr->u.c.an_log_value[1] = pC->u.v.an_log[1];
325 } else
326 found = 0;
327 break;
328 case HPI_CONTROL_MULTIPLEXER:
329 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
330 phr->u.c.param1 = pC->u.x.source_node_type;
331 phr->u.c.param2 = pC->u.x.source_node_index;
332 } else {
333 found = 0;
334 }
335 break;
336 case HPI_CONTROL_CHANNEL_MODE:
337 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
338 phr->u.c.param1 = pC->u.m.mode;
339 else
340 found = 0;
341 break;
342 case HPI_CONTROL_LEVEL:
343 if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
344 phr->u.c.an_log_value[0] = pC->u.l.an_log[0];
345 phr->u.c.an_log_value[1] = pC->u.l.an_log[1];
346 } else
347 found = 0;
348 break;
349 case HPI_CONTROL_TUNER:
350 if (phm->u.c.attribute == HPI_TUNER_FREQ)
351 phr->u.c.param1 = pC->u.t.freq_ink_hz;
352 else if (phm->u.c.attribute == HPI_TUNER_BAND)
353 phr->u.c.param1 = pC->u.t.band;
354 else if ((phm->u.c.attribute == HPI_TUNER_LEVEL)
355 && (phm->u.c.param1 == HPI_TUNER_LEVEL_AVERAGE))
356 if (pC->u.t.level == HPI_ERROR_ILLEGAL_CACHE_VALUE) {
357 phr->u.c.param1 = 0;
358 phr->error =
359 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
360 } else
361 phr->u.c.param1 = pC->u.t.level;
362 else
363 found = 0;
364 break;
365 case HPI_CONTROL_AESEBU_RECEIVER:
366 if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS)
367 phr->u.c.param1 = pC->u.aes3rx.error_status;
368 else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
369 phr->u.c.param1 = pC->u.aes3rx.source;
370 else
371 found = 0;
372 break;
373 case HPI_CONTROL_AESEBU_TRANSMITTER:
374 if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
375 phr->u.c.param1 = pC->u.aes3tx.format;
376 else
377 found = 0;
378 break;
379 case HPI_CONTROL_TONEDETECTOR:
380 if (phm->u.c.attribute == HPI_TONEDETECTOR_STATE)
381 phr->u.c.param1 = pC->u.tone.state;
382 else
383 found = 0;
384 break;
385 case HPI_CONTROL_SILENCEDETECTOR:
386 if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) {
387 phr->u.c.param1 = pC->u.silence.state;
388 phr->u.c.param2 = pC->u.silence.count;
389 } else
390 found = 0;
391 break;
392 case HPI_CONTROL_MICROPHONE:
393 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
394 phr->u.c.param1 = pC->u.phantom_power.state;
395 else
396 found = 0;
397 break;
398 case HPI_CONTROL_SAMPLECLOCK:
399 if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
400 phr->u.c.param1 = pC->u.clk.source;
401 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) {
402 if (pC->u.clk.source_index ==
403 HPI_ERROR_ILLEGAL_CACHE_VALUE) {
404 phr->u.c.param1 = 0;
405 phr->error =
406 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
407 } else
408 phr->u.c.param1 = pC->u.clk.source_index;
409 } else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
410 phr->u.c.param1 = pC->u.clk.sample_rate;
411 else
412 found = 0;
413 break;
414 case HPI_CONTROL_PAD:
415
416 if (!(p_pad->field_valid_flags & (1 <<
417 HPI_CTL_ATTR_INDEX(phm->u.c.
418 attribute)))) {
419 phr->error = HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
420 break;
421 }
422
423 if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID)
424 phr->u.c.param1 = p_pad->pI;
425 else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE)
426 phr->u.c.param1 = p_pad->pTY;
427 else {
428 unsigned int index =
429 HPI_CTL_ATTR_INDEX(phm->u.c.attribute) - 1;
430 unsigned int offset = phm->u.c.param1;
431 unsigned int pad_string_len, field_size;
432 char *pad_string;
433 unsigned int tocopy;
434
435 HPI_DEBUG_LOG(VERBOSE, "PADS HPI_PADS_ %d\n",
436 phm->u.c.attribute);
437
438 if (index > ARRAY_SIZE(pad_desc) - 1) {
439 phr->error =
440 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
441 break;
442 }
443
444 pad_string = ((char *)p_pad) + pad_desc[index].offset;
445 field_size = pad_desc[index].field_size;
446
447 pad_string[field_size - 1] = 0;
448
449 pad_string_len = strlen(pad_string) + 1;
450
451 if (offset > pad_string_len) {
452 phr->error = HPI_ERROR_INVALID_CONTROL_VALUE;
453 break;
454 }
455
456 tocopy = pad_string_len - offset;
457 if (tocopy > sizeof(phr->u.cu.chars8.sz_data))
458 tocopy = sizeof(phr->u.cu.chars8.sz_data);
459
460 HPI_DEBUG_LOG(VERBOSE,
461 "PADS memcpy(%d), offset %d \n", tocopy,
462 offset);
463 memcpy(phr->u.cu.chars8.sz_data, &pad_string[offset],
464 tocopy);
465
466 phr->u.cu.chars8.remaining_chars =
467 pad_string_len - offset - tocopy;
468 }
469 break;
470 default:
471 found = 0;
472 break;
473 }
474
475 if (found)
476 HPI_DEBUG_LOG(VERBOSE,
477 "cached adap %d, ctl %d, type %d, attr %d\n",
478 phm->adapter_index, pI->control_index,
479 pI->control_type, phm->u.c.attribute);
480 else
481 HPI_DEBUG_LOG(VERBOSE,
482 "uncached adap %d, ctl %d, ctl type %d\n",
483 phm->adapter_index, pI->control_index,
484 pI->control_type);
485
486 if (found)
487 phr->size =
488 sizeof(struct hpi_response_header) +
489 sizeof(struct hpi_control_res);
490
491 return found;
492}
493
494
495
496
497
498
499
500void hpi_sync_control_cache(struct hpi_control_cache *p_cache,
501 struct hpi_message *phm, struct hpi_response *phr)
502{
503 u16 control_index;
504 struct hpi_control_cache_single *pC;
505 struct hpi_control_cache_info *pI;
506
507 if (phr->error)
508 return;
509
510 if (!find_control(phm, p_cache, &pI, &control_index))
511 return;
512
513
514
515
516 pC = (struct hpi_control_cache_single *)pI;
517
518 switch (pI->control_type) {
519 case HPI_CONTROL_VOLUME:
520 if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
521 pC->u.v.an_log[0] = phr->u.c.an_log_value[0];
522 pC->u.v.an_log[1] = phr->u.c.an_log_value[1];
523 }
524 break;
525 case HPI_CONTROL_MULTIPLEXER:
526
527 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
528 pC->u.x.source_node_type = (u16)phm->u.c.param1;
529 pC->u.x.source_node_index = (u16)phm->u.c.param2;
530 }
531 break;
532 case HPI_CONTROL_CHANNEL_MODE:
533
534 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
535 pC->u.m.mode = (u16)phm->u.c.param1;
536 break;
537 case HPI_CONTROL_LEVEL:
538 if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
539 pC->u.v.an_log[0] = phr->u.c.an_log_value[0];
540 pC->u.v.an_log[1] = phr->u.c.an_log_value[1];
541 }
542 break;
543 case HPI_CONTROL_MICROPHONE:
544 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
545 pC->u.phantom_power.state = (u16)phm->u.c.param1;
546 break;
547 case HPI_CONTROL_AESEBU_TRANSMITTER:
548 if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
549 pC->u.aes3tx.format = phm->u.c.param1;
550 break;
551 case HPI_CONTROL_AESEBU_RECEIVER:
552 if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
553 pC->u.aes3rx.source = phm->u.c.param1;
554 break;
555 case HPI_CONTROL_SAMPLECLOCK:
556 if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
557 pC->u.clk.source = (u16)phm->u.c.param1;
558 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX)
559 pC->u.clk.source_index = (u16)phm->u.c.param1;
560 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
561 pC->u.clk.sample_rate = phm->u.c.param1;
562 break;
563 default:
564 break;
565 }
566}
567
568struct hpi_control_cache *hpi_alloc_control_cache(const u32
569 number_of_controls, const u32 size_in_bytes,
570 struct hpi_control_cache_info *pDSP_control_buffer)
571{
572 struct hpi_control_cache *p_cache =
573 kmalloc(sizeof(*p_cache), GFP_KERNEL);
574 if (!p_cache)
575 return NULL;
576 p_cache->p_info =
577 kmalloc(sizeof(*p_cache->p_info) * number_of_controls,
578 GFP_KERNEL);
579 if (!p_cache->p_info) {
580 kfree(p_cache);
581 return NULL;
582 }
583 p_cache->cache_size_in_bytes = size_in_bytes;
584 p_cache->control_count = number_of_controls;
585 p_cache->p_cache =
586 (struct hpi_control_cache_single *)pDSP_control_buffer;
587 p_cache->init = 0;
588 return p_cache;
589}
590
591void hpi_free_control_cache(struct hpi_control_cache *p_cache)
592{
593 if (p_cache->init) {
594 kfree(p_cache->p_info);
595 p_cache->p_info = NULL;
596 p_cache->init = 0;
597 kfree(p_cache);
598 }
599}
600
601static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
602{
603
604 switch (phm->function) {
605 case HPI_SUBSYS_OPEN:
606 case HPI_SUBSYS_CLOSE:
607 case HPI_SUBSYS_DRIVER_UNLOAD:
608 phr->error = 0;
609 break;
610 case HPI_SUBSYS_DRIVER_LOAD:
611 wipe_adapter_list();
612 hpios_alistlock_init(&adapters);
613 phr->error = 0;
614 break;
615 case HPI_SUBSYS_GET_INFO:
616 subsys_get_adapters(phr);
617 break;
618 case HPI_SUBSYS_CREATE_ADAPTER:
619 case HPI_SUBSYS_DELETE_ADAPTER:
620 phr->error = 0;
621 break;
622 default:
623 phr->error = HPI_ERROR_INVALID_FUNC;
624 break;
625 }
626}
627
628void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr)
629{
630 switch (phm->type) {
631 case HPI_TYPE_MESSAGE:
632 switch (phm->object) {
633 case HPI_OBJ_SUBSYSTEM:
634 subsys_message(phm, phr);
635 break;
636 }
637 break;
638
639 default:
640 phr->error = HPI_ERROR_INVALID_TYPE;
641 break;
642 }
643}
644