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:
351 struct hpi_control_cache_single *pCT =
352 (struct hpi_control_cache_single *)pI;
353 if (phm->u.c.attribute == HPI_TUNER_FREQ)
354 phr->u.c.param1 = pCT->u.t.freq_ink_hz;
355 else if (phm->u.c.attribute == HPI_TUNER_BAND)
356 phr->u.c.param1 = pCT->u.t.band;
357 else if ((phm->u.c.attribute == HPI_TUNER_LEVEL)
358 && (phm->u.c.param1 ==
359 HPI_TUNER_LEVEL_AVERAGE))
360 phr->u.c.param1 = pCT->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) {
405 phr->error = HPI_ERROR_INVALID_OPERATION;
407 phr->u.c.param1 = pC->u.clk.source_index;
408 } else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
409 phr->u.c.param1 = pC->u.clk.sample_rate;
413 case HPI_CONTROL_PAD:
415 if (!(p_pad->field_valid_flags & (1 <<
416 HPI_CTL_ATTR_INDEX(phm->u.c.
418 phr->error = HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
422 if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID)
423 phr->u.c.param1 = p_pad->pI;
424 else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE)
425 phr->u.c.param1 = p_pad->pTY;
428 HPI_CTL_ATTR_INDEX(phm->u.c.attribute) - 1;
429 unsigned int offset = phm->u.c.param1;
430 unsigned int pad_string_len, field_size;
434 HPI_DEBUG_LOG(VERBOSE, "PADS HPI_PADS_ %d\n",
437 if (index > ARRAY_SIZE(pad_desc) - 1) {
439 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
443 pad_string = ((char *)p_pad) + pad_desc[index].offset;
444 field_size = pad_desc[index].field_size;
445 /* Ensure null terminator */
446 pad_string[field_size - 1] = 0;
448 pad_string_len = strlen(pad_string) + 1;
450 if (offset > pad_string_len) {
451 phr->error = HPI_ERROR_INVALID_CONTROL_VALUE;
455 tocopy = pad_string_len - offset;
456 if (tocopy > sizeof(phr->u.cu.chars8.sz_data))
457 tocopy = sizeof(phr->u.cu.chars8.sz_data);
459 HPI_DEBUG_LOG(VERBOSE,
460 "PADS memcpy(%d), offset %d \n", tocopy,
462 memcpy(phr->u.cu.chars8.sz_data, &pad_string[offset],
465 phr->u.cu.chars8.remaining_chars =
466 pad_string_len - offset - tocopy;
475 HPI_DEBUG_LOG(VERBOSE,
476 "cached adap %d, ctl %d, type %d, attr %d\n",
477 phm->adapter_index, pI->control_index,
478 pI->control_type, phm->u.c.attribute);
480 HPI_DEBUG_LOG(VERBOSE,
481 "uncached adap %d, ctl %d, ctl type %d\n",
482 phm->adapter_index, pI->control_index,
487 sizeof(struct hpi_response_header) +
488 sizeof(struct hpi_control_res);
493 /** Updates the cache with Set values.
495 Only update if no error.
496 Volume and Level return the limited values in the response, so use these
497 Multiplexer does so use sent values
499 void hpi_sync_control_cache(struct hpi_control_cache *p_cache,
500 struct hpi_message *phm, struct hpi_response *phr)
503 struct hpi_control_cache_single *pC;
504 struct hpi_control_cache_info *pI;
506 if (!find_control(phm, p_cache, &pI, &control_index))
509 /* pC is the default cached control strucure.
510 May be cast to something else in the following switch statement.
512 pC = (struct hpi_control_cache_single *)pI;
514 switch (pI->control_type) {
515 case HPI_CONTROL_VOLUME:
516 if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
517 pC->u.v.an_log[0] = phr->u.c.an_log_value[0];
518 pC->u.v.an_log[1] = phr->u.c.an_log_value[1];
521 case HPI_CONTROL_MULTIPLEXER:
522 /* mux does not return its setting on Set command. */
525 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
526 pC->u.x.source_node_type = (u16)phm->u.c.param1;
527 pC->u.x.source_node_index = (u16)phm->u.c.param2;
530 case HPI_CONTROL_CHANNEL_MODE:
531 /* 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:
550 if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
551 pC->u.aes3tx.format = phm->u.c.param1;
553 case HPI_CONTROL_AESEBU_RECEIVER:
556 if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
557 pC->u.aes3rx.source = phm->u.c.param1;
559 case HPI_CONTROL_SAMPLECLOCK:
562 if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
563 pC->u.clk.source = (u16)phm->u.c.param1;
564 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX)
565 pC->u.clk.source_index = (u16)phm->u.c.param1;
566 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
567 pC->u.clk.sample_rate = phm->u.c.param1;
574 struct hpi_control_cache *hpi_alloc_control_cache(const u32
575 number_of_controls, const u32 size_in_bytes,
576 struct hpi_control_cache_info *pDSP_control_buffer)
578 struct hpi_control_cache *p_cache =
579 kmalloc(sizeof(*p_cache), GFP_KERNEL);
580 p_cache->cache_size_in_bytes = size_in_bytes;
581 p_cache->control_count = number_of_controls;
583 (struct hpi_control_cache_single *)pDSP_control_buffer;
586 kmalloc(sizeof(*p_cache->p_info) * p_cache->control_count,
591 void hpi_free_control_cache(struct hpi_control_cache *p_cache)
593 if ((p_cache->init) && (p_cache->p_info)) {
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;