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"
31
struct hpi_adapters_list {
32
struct hpios_spinlock list_lock;
33
struct hpi_adapter_obj adapter[HPI_MAX_ADAPTERS];
37
static struct hpi_adapters_list adapters;
40
* Given an HPI Message that was sent out and a response that was received,
41
* validate that the response has the correct fields filled in,
42
* i.e ObjectType, Function etc
44
u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr)
48
if ((phr->type != HPI_TYPE_RESPONSE)
49
|| (phr->object != phm->object)
50
|| (phr->function != phm->function))
51
error = HPI_ERROR_INVALID_RESPONSE;
56
u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
59
/*HPI_ASSERT(pao->wAdapterType); */
61
hpios_alistlock_lock(&adapters);
63
if (pao->index >= HPI_MAX_ADAPTERS) {
64
retval = HPI_ERROR_BAD_ADAPTER_NUMBER;
68
if (adapters.adapter[pao->index].adapter_type) {
70
retval = HPI_DUPLICATE_ADAPTER_NUMBER;
74
adapters.adapter[pao->index] = *pao;
75
hpios_dsplock_init(&adapters.adapter[pao->index]);
76
adapters.gw_num_adapters++;
79
hpios_alistlock_un_lock(&adapters);
83
void hpi_delete_adapter(struct hpi_adapter_obj *pao)
85
memset(pao, 0, sizeof(struct hpi_adapter_obj));
87
hpios_alistlock_lock(&adapters);
88
adapters.gw_num_adapters--; /* dec the number of adapters */
89
hpios_alistlock_un_lock(&adapters);
93
* FindAdapter returns a pointer to the struct hpi_adapter_obj with
94
* index wAdapterIndex in an HPI_ADAPTERS_LIST structure.
97
struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index)
99
struct hpi_adapter_obj *pao = NULL;
101
if (adapter_index >= HPI_MAX_ADAPTERS) {
102
HPI_DEBUG_LOG(VERBOSE, "find_adapter invalid index %d ",
107
pao = &adapters.adapter[adapter_index];
108
if (pao->adapter_type != 0) {
110
HPI_DEBUG_LOG(VERBOSE, "Found adapter index %d\n",
116
HPI_DEBUG_LOG(VERBOSE, "No adapter index %d\n",
125
* wipe an HPI_ADAPTERS_LIST structure.
128
static void wipe_adapter_list(void
131
memset(&adapters, 0, sizeof(adapters));
135
* SubSysGetAdapters fills awAdapterList in an struct hpi_response structure
136
* with all adapters in the given HPI_ADAPTERS_LIST.
139
static void subsys_get_adapters(struct hpi_response *phr)
141
/* fill in the response adapter array with the position */
142
/* identified by the adapter number/index of the adapters in */
144
/* i.e. if we have an A120 with it's jumper set to */
145
/* Adapter Number 2 then put an Adapter type A120 in the */
146
/* array in position 1 */
147
/* NOTE: AdapterNumber is 1..N, Index is 0..N-1 */
150
/* output: wNumAdapters */
155
struct hpi_adapter_obj *pao = NULL;
157
HPI_DEBUG_LOG(VERBOSE, "subsys_get_adapters\n");
159
/* for each adapter, place it's type in the position of the array */
160
/* corresponding to it's adapter number */
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;
168
phr->u.s.aw_adapter_list[pao->index] = pao->adapter_type;
171
phr->u.s.num_adapters = adapters.gw_num_adapters;
172
phr->error = 0; /* the function completed OK; */
175
static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
181
if ((!pC->init) && (pC->p_cache != NULL) && (pC->control_count)
182
&& (pC->cache_size_in_bytes)
187
p_master_cache = (u32 *)pC->p_cache;
188
HPI_DEBUG_LOG(VERBOSE, "check %d controls\n",
190
for (i = 0; i < pC->control_count; i++) {
191
struct hpi_control_cache_info *info =
192
(struct hpi_control_cache_info *)
195
if (info->control_type) {
196
pC->p_info[i] = info;
199
pC->p_info[i] = NULL;
201
if (info->size_in32bit_words)
202
p_master_cache += info->size_in32bit_words;
206
hpi_control_cache_single) /
209
HPI_DEBUG_LOG(VERBOSE,
210
"cached %d, pinfo %p index %d type %d\n",
211
cached, pC->p_info[i], info->control_index,
215
We didn't find anything to cache, so try again later !
225
static 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)
229
*pw_control_index = phm->obj_index;
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);
238
*pI = p_cache->p_info[*pw_control_index];
240
HPI_DEBUG_LOG(VERBOSE, "uncached adap %d, control %d\n",
241
phm->adapter_index, *pw_control_index);
244
HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n",
245
(*pI)->control_type);
250
/** Used by the kernel driver to figure out if a buffer needs mapping.
252
short hpi_check_buffer_mapping(struct hpi_control_cache *p_cache,
253
struct hpi_message *phm, void **p, unsigned int *pN)
257
if ((phm->function == HPI_CONTROL_GET_STATE)
258
&& (phm->object == HPI_OBJ_CONTROLEX)
261
struct hpi_control_cache_info *pI;
263
if (!find_control(phm, p_cache, &pI, &control_index))
269
/* allow unified treatment of several string fields within struct */
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) }
274
struct pad_ofs_size {
276
unsigned int field_size;
279
static struct pad_ofs_size pad_desc[] = {
280
HPICMN_PAD_OFS_AND_SIZE(c_channel), /* HPI_PAD_CHANNEL_NAME */
281
HPICMN_PAD_OFS_AND_SIZE(c_artist), /* HPI_PAD_ARTIST */
282
HPICMN_PAD_OFS_AND_SIZE(c_title), /* HPI_PAD_TITLE */
283
HPICMN_PAD_OFS_AND_SIZE(c_comment), /* HPI_PAD_COMMENT */
286
/** CheckControlCache checks the cache and fills the struct hpi_response
287
* accordingly. It returns one if a cache hit occurred, zero otherwise.
289
short hpi_check_control_cache(struct hpi_control_cache *p_cache,
290
struct hpi_message *phm, struct hpi_response *phr)
294
struct hpi_control_cache_info *pI;
295
struct hpi_control_cache_single *pC;
296
struct hpi_control_cache_pad *p_pad;
298
if (!find_control(phm, p_cache, &pI, &control_index))
303
/* pC is the default cached control strucure. May be cast to
304
something else in the following switch statement.
306
pC = (struct hpi_control_cache_single *)pI;
307
p_pad = (struct hpi_control_cache_pad *)pI;
309
switch (pI->control_type) {
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];
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];
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;
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;
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];
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) {
359
HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
361
phr->u.c.param1 = pC->u.t.level;
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;
373
case HPI_CONTROL_AESEBU_TRANSMITTER:
374
if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
375
phr->u.c.param1 = pC->u.aes3tx.format;
379
case HPI_CONTROL_TONEDETECTOR:
380
if (phm->u.c.attribute == HPI_TONEDETECTOR_STATE)
381
phr->u.c.param1 = pC->u.tone.state;
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;
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;
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) {
406
HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
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;
414
case HPI_CONTROL_PAD:
416
if (!(p_pad->field_valid_flags & (1 <<
417
HPI_CTL_ATTR_INDEX(phm->u.c.
419
phr->error = HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
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;
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;
435
HPI_DEBUG_LOG(VERBOSE, "PADS HPI_PADS_ %d\n",
438
if (index > ARRAY_SIZE(pad_desc) - 1) {
440
HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
444
pad_string = ((char *)p_pad) + pad_desc[index].offset;
445
field_size = pad_desc[index].field_size;
446
/* Ensure null terminator */
447
pad_string[field_size - 1] = 0;
449
pad_string_len = strlen(pad_string) + 1;
451
if (offset > pad_string_len) {
452
phr->error = HPI_ERROR_INVALID_CONTROL_VALUE;
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);
460
HPI_DEBUG_LOG(VERBOSE,
461
"PADS memcpy(%d), offset %d \n", tocopy,
463
memcpy(phr->u.cu.chars8.sz_data, &pad_string[offset],
466
phr->u.cu.chars8.remaining_chars =
467
pad_string_len - offset - tocopy;
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);
481
HPI_DEBUG_LOG(VERBOSE,
482
"uncached adap %d, ctl %d, ctl type %d\n",
483
phm->adapter_index, pI->control_index,
488
sizeof(struct hpi_response_header) +
489
sizeof(struct hpi_control_res);
494
/** Updates the cache with Set values.
496
Only update if no error.
497
Volume and Level return the limited values in the response, so use these
498
Multiplexer does so use sent values
500
void hpi_sync_control_cache(struct hpi_control_cache *p_cache,
501
struct hpi_message *phm, struct hpi_response *phr)
504
struct hpi_control_cache_single *pC;
505
struct hpi_control_cache_info *pI;
510
if (!find_control(phm, p_cache, &pI, &control_index))
513
/* pC is the default cached control strucure.
514
May be cast to something else in the following switch statement.
516
pC = (struct hpi_control_cache_single *)pI;
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];
525
case HPI_CONTROL_MULTIPLEXER:
526
/* mux does not return its setting on Set command. */
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;
532
case HPI_CONTROL_CHANNEL_MODE:
533
/* mode does not return its setting on Set command. */
534
if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
535
pC->u.m.mode = (u16)phm->u.c.param1;
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];
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;
547
case HPI_CONTROL_AESEBU_TRANSMITTER:
548
if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
549
pC->u.aes3tx.format = phm->u.c.param1;
551
case HPI_CONTROL_AESEBU_RECEIVER:
552
if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
553
pC->u.aes3rx.source = phm->u.c.param1;
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;
568
struct 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)
572
struct hpi_control_cache *p_cache =
573
kmalloc(sizeof(*p_cache), GFP_KERNEL);
577
kmalloc(sizeof(*p_cache->p_info) * number_of_controls,
579
if (!p_cache->p_info) {
583
p_cache->cache_size_in_bytes = size_in_bytes;
584
p_cache->control_count = number_of_controls;
586
(struct hpi_control_cache_single *)pDSP_control_buffer;
591
void hpi_free_control_cache(struct hpi_control_cache *p_cache)
594
kfree(p_cache->p_info);
595
p_cache->p_info = NULL;
601
static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
604
switch (phm->function) {
605
case HPI_SUBSYS_OPEN:
606
case HPI_SUBSYS_CLOSE:
607
case HPI_SUBSYS_DRIVER_UNLOAD:
610
case HPI_SUBSYS_DRIVER_LOAD:
612
hpios_alistlock_init(&adapters);
615
case HPI_SUBSYS_GET_INFO:
616
subsys_get_adapters(phr);
618
case HPI_SUBSYS_CREATE_ADAPTER:
619
case HPI_SUBSYS_DELETE_ADAPTER:
623
phr->error = HPI_ERROR_INVALID_FUNC;
628
void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr)
631
case HPI_TYPE_MESSAGE:
632
switch (phm->object) {
633
case HPI_OBJ_SUBSYSTEM:
634
subsys_message(phm, phr);
640
phr->error = HPI_ERROR_INVALID_TYPE;