1
/******************************************************************************
3
AudioScience HPI driver
4
Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
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;
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.
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
21
Common functions used by hpixxxx.c modules
23
(C) Copyright AudioScience Inc. 1998-2003
24
*******************************************************************************/
25
#define SOURCEFILE_NAME "hpicmn.c"
27
#include "hpi_internal.h"
29
#include "hpimsginit.h"
33
struct hpi_adapters_list {
34
struct hpios_spinlock list_lock;
35
struct hpi_adapter_obj adapter[HPI_MAX_ADAPTERS];
39
static struct hpi_adapters_list adapters;
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
46
u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr)
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;
53
if (phr->object != phm->object) {
54
HPI_DEBUG_LOG(ERROR, "header object %d invalid\n",
56
return HPI_ERROR_INVALID_RESPONSE;
59
if (phr->function != phm->function) {
60
HPI_DEBUG_LOG(ERROR, "header function %d invalid\n",
62
return HPI_ERROR_INVALID_RESPONSE;
68
u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
71
/*HPI_ASSERT(pao->wAdapterType); */
73
hpios_alistlock_lock(&adapters);
75
if (pao->index >= HPI_MAX_ADAPTERS) {
76
retval = HPI_ERROR_BAD_ADAPTER_NUMBER;
80
if (adapters.adapter[pao->index].adapter_type) {
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);
92
retval = HPI_ERROR_DUPLICATE_ADAPTER_NUMBER;
96
adapters.adapter[pao->index] = *pao;
97
hpios_dsplock_init(&adapters.adapter[pao->index]);
98
adapters.gw_num_adapters++;
101
hpios_alistlock_unlock(&adapters);
105
void hpi_delete_adapter(struct hpi_adapter_obj *pao)
107
if (!pao->adapter_type) {
108
HPI_DEBUG_LOG(ERROR, "removing null adapter?\n");
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);
120
* FindAdapter returns a pointer to the struct hpi_adapter_obj with
121
* index wAdapterIndex in an HPI_ADAPTERS_LIST structure.
124
struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index)
126
struct hpi_adapter_obj *pao = NULL;
128
if (adapter_index >= HPI_MAX_ADAPTERS) {
129
HPI_DEBUG_LOG(VERBOSE, "find_adapter invalid index %d\n",
134
pao = &adapters.adapter[adapter_index];
135
if (pao->adapter_type != 0) {
137
HPI_DEBUG_LOG(VERBOSE, "Found adapter index %d\n",
143
HPI_DEBUG_LOG(VERBOSE, "No adapter index %d\n",
152
* wipe an HPI_ADAPTERS_LIST structure.
155
static void wipe_adapter_list(void)
157
memset(&adapters, 0, sizeof(adapters));
160
static void subsys_get_adapter(struct hpi_message *phm,
161
struct hpi_response *phr)
163
int count = phm->obj_index;
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) {
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;
179
phr->u.s.adapter_index = 0;
180
phr->u.s.adapter_type = 0;
181
phr->error = HPI_ERROR_BAD_ADAPTER_NUMBER;
185
static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
198
if (pC->control_count && pC->cache_size_in_bytes) {
199
char *p_master_cache;
200
unsigned int byte_count = 0;
202
p_master_cache = (char *)pC->p_cache;
203
HPI_DEBUG_LOG(DEBUG, "check %d controls\n",
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];
210
if (!info->size_in32bit_words) {
213
"adap %d cache not ready?\n",
217
/* The cache is invalid.
218
* Minimum valid entry size is
219
* sizeof(struct hpi_control_cache_info)
222
"adap %d zero size cache entry %d\n",
227
if (info->control_type) {
228
pC->p_info[info->control_index] = info;
230
} else { /* dummy cache entry */
231
pC->p_info[info->control_index] = NULL;
234
byte_count += info->size_in32bit_words * 4;
236
HPI_DEBUG_LOG(VERBOSE,
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);
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
246
if (byte_count >= pC->cache_size_in_bytes)
248
/* have seen last control index */
249
if (info->control_index == pC->control_count - 1)
253
if (byte_count != pC->cache_size_in_bytes)
254
HPI_DEBUG_LOG(WARNING,
255
"adap %d bytecount %d != cache size %d\n",
256
pC->adap_idx, byte_count,
257
pC->cache_size_in_bytes);
260
"adap %d cache good, bytecount == cache size = %d\n",
261
pC->adap_idx, byte_count);
263
pC->init = (u16)cached;
270
static short find_control(u16 control_index,
271
struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI)
273
if (!control_cache_alloc_check(p_cache)) {
274
HPI_DEBUG_LOG(VERBOSE,
275
"control_cache_alloc_check() failed %d\n",
280
*pI = p_cache->p_info[control_index];
282
HPI_DEBUG_LOG(VERBOSE, "Uncached Control %d\n",
286
HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n",
287
(*pI)->control_type);
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) }
297
struct pad_ofs_size {
299
unsigned int field_size;
302
static const struct pad_ofs_size pad_desc[] = {
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 */
309
/** CheckControlCache checks the cache and fills the struct hpi_response
310
* accordingly. It returns one if a cache hit occurred, zero otherwise.
312
short hpi_check_control_cache(struct hpi_control_cache *p_cache,
313
struct hpi_message *phm, struct hpi_response *phr)
316
struct hpi_control_cache_info *pI;
317
struct hpi_control_cache_single *pC;
318
size_t response_size;
319
if (!find_control(phm->obj_index, p_cache, &pI)) {
320
HPI_DEBUG_LOG(VERBOSE,
321
"HPICMN find_control() failed for adap %d\n",
328
/* set the default response size */
330
sizeof(struct hpi_response_header) +
331
sizeof(struct hpi_control_res);
333
/* pC is the default cached control strucure. May be cast to
334
something else in the following switch statement.
336
pC = (struct hpi_control_cache_single *)pI;
338
switch (pI->control_type) {
340
case HPI_CONTROL_METER:
341
if (phm->u.c.attribute == HPI_METER_PEAK) {
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];
344
} else if (phm->u.c.attribute == HPI_METER_RMS) {
345
if (pC->u.meter.an_logRMS[0] ==
346
HPI_CACHE_INVALID_SHORT) {
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;
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];
360
case HPI_CONTROL_VOLUME:
361
if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
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];
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)
368
HPI_BITMASK_ALL_CHANNELS;
373
HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
380
case HPI_CONTROL_MULTIPLEXER:
381
if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
382
phr->u.c.param1 = pC->u.mux.source_node_type;
383
phr->u.c.param2 = pC->u.mux.source_node_index;
388
case HPI_CONTROL_CHANNEL_MODE:
389
if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
390
phr->u.c.param1 = pC->u.mode.mode;
394
case HPI_CONTROL_LEVEL:
395
if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
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];
401
case HPI_CONTROL_TUNER:
402
if (phm->u.c.attribute == HPI_TUNER_FREQ)
403
phr->u.c.param1 = pC->u.tuner.freq_ink_hz;
404
else if (phm->u.c.attribute == HPI_TUNER_BAND)
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;
411
HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
413
phr->u.cu.tuner.s_level =
414
pC->u.tuner.s_level_avg;
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)
422
phr->u.c.param1 = pC->u.aes3rx.format;
426
case HPI_CONTROL_AESEBU_TRANSMITTER:
427
if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
428
phr->u.c.param1 = pC->u.aes3tx.format;
432
case HPI_CONTROL_TONEDETECTOR:
433
if (phm->u.c.attribute == HPI_TONEDETECTOR_STATE)
434
phr->u.c.param1 = pC->u.tone.state;
438
case HPI_CONTROL_SILENCEDETECTOR:
439
if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) {
440
phr->u.c.param1 = pC->u.silence.state;
444
case HPI_CONTROL_MICROPHONE:
445
if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
446
phr->u.c.param1 = pC->u.microphone.phantom_state;
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 ==
455
HPI_CACHE_INVALID_UINT16) {
458
HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
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;
466
case HPI_CONTROL_PAD:{
467
struct hpi_control_cache_pad *p_pad;
468
p_pad = (struct hpi_control_cache_pad *)pI;
470
if (!(p_pad->field_valid_flags & (1 <<
471
HPI_CTL_ATTR_INDEX(phm->u.c.
474
HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
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;
484
HPI_CTL_ATTR_INDEX(phm->u.c.
486
unsigned int offset = phm->u.c.param1;
487
unsigned int pad_string_len, field_size;
491
if (index > ARRAY_SIZE(pad_desc) - 1) {
493
HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
499
pad_desc[index].offset;
500
field_size = pad_desc[index].field_size;
501
/* Ensure null terminator */
502
pad_string[field_size - 1] = 0;
504
pad_string_len = strlen(pad_string) + 1;
506
if (offset > pad_string_len) {
508
HPI_ERROR_INVALID_CONTROL_VALUE;
512
tocopy = pad_string_len - offset;
513
if (tocopy > sizeof(phr->u.cu.chars8.sz_data))
514
tocopy = sizeof(phr->u.cu.chars8.
517
memcpy(phr->u.cu.chars8.sz_data,
518
&pad_string[offset], tocopy);
520
phr->u.cu.chars8.remaining_chars =
521
pad_string_len - offset - tocopy;
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);
535
phr->size = (u16)response_size;
540
/** Updates the cache with Set values.
542
Only update if no error.
543
Volume and Level return the limited values in the response, so use these
544
Multiplexer does so use sent values
546
void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache,
547
struct hpi_message *phm, struct hpi_response *phr)
549
struct hpi_control_cache_single *pC;
550
struct hpi_control_cache_info *pI;
555
if (!find_control(phm->obj_index, p_cache, &pI)) {
556
HPI_DEBUG_LOG(VERBOSE,
557
"HPICMN find_control() failed for adap %d\n",
562
/* pC is the default cached control strucure.
563
May be cast to something else in the following switch statement.
565
pC = (struct hpi_control_cache_single *)pI;
567
switch (pI->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) {
574
pC->u.vol.flags |= HPI_VOLUME_FLAG_MUTED;
576
pC->u.vol.flags &= ~HPI_VOLUME_FLAG_MUTED;
579
case HPI_CONTROL_MULTIPLEXER:
580
/* mux does not return its setting on Set command. */
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;
586
case HPI_CONTROL_CHANNEL_MODE:
587
/* mode does not return its setting on Set command. */
588
if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
589
pC->u.mode.mode = (u16)phm->u.c.param1;
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];
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;
601
case HPI_CONTROL_AESEBU_TRANSMITTER:
602
if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
603
pC->u.aes3tx.format = phm->u.c.param1;
605
case HPI_CONTROL_AESEBU_RECEIVER:
606
if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
607
pC->u.aes3rx.format = phm->u.c.param1;
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;
622
/** Allocate control cache.
624
\return Cache pointer, or NULL if allocation fails.
626
struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count,
627
const u32 size_in_bytes, u8 *p_dsp_control_buffer)
629
struct hpi_control_cache *p_cache =
630
kmalloc(sizeof(*p_cache), GFP_KERNEL);
634
p_cache->p_info = kzalloc(sizeof(*p_cache->p_info) * control_count,
636
if (!p_cache->p_info) {
640
p_cache->cache_size_in_bytes = size_in_bytes;
641
p_cache->control_count = control_count;
642
p_cache->p_cache = p_dsp_control_buffer;
647
void hpi_free_control_cache(struct hpi_control_cache *p_cache)
650
kfree(p_cache->p_info);
655
static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
657
hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, 0);
659
switch (phm->function) {
660
case HPI_SUBSYS_OPEN:
661
case HPI_SUBSYS_CLOSE:
662
case HPI_SUBSYS_DRIVER_UNLOAD:
664
case HPI_SUBSYS_DRIVER_LOAD:
666
hpios_alistlock_init(&adapters);
668
case HPI_SUBSYS_GET_ADAPTER:
669
subsys_get_adapter(phm, phr);
671
case HPI_SUBSYS_GET_NUM_ADAPTERS:
672
phr->u.s.num_adapters = adapters.gw_num_adapters;
674
case HPI_SUBSYS_CREATE_ADAPTER:
677
phr->error = HPI_ERROR_INVALID_FUNC;
682
void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr)
685
case HPI_TYPE_REQUEST:
686
switch (phm->object) {
687
case HPI_OBJ_SUBSYSTEM:
688
subsys_message(phm, phr);
694
phr->error = HPI_ERROR_INVALID_TYPE;