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 type %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
;
233 byte_count
+= info
->size_in32bit_words
* 4;
235 HPI_DEBUG_LOG(VERBOSE
,
236 "cached %d, pinfo %p index %d type %d size %d\n",
237 cached
, pC
->p_info
[info
->control_index
],
238 info
->control_index
, info
->control_type
,
239 info
->size_in32bit_words
);
241 /* quit loop early if whole cache has been scanned.
242 * dwControlCount is the maximum possible entries
243 * but some may be absent from the cache
245 if (byte_count
>= pC
->cache_size_in_bytes
)
247 /* have seen last control index */
248 if (info
->control_index
== pC
->control_count
- 1)
252 if (byte_count
!= pC
->cache_size_in_bytes
)
253 HPI_DEBUG_LOG(WARNING
,
254 "adap %d bytecount %d != cache size %d\n",
255 pC
->adap_idx
, byte_count
,
256 pC
->cache_size_in_bytes
);
259 "adap %d cache good, bytecount == cache size = %d\n",
260 pC
->adap_idx
, byte_count
);
262 pC
->init
= (u16
)cached
;
269 static short find_control(u16 control_index
,
270 struct hpi_control_cache
*p_cache
, struct hpi_control_cache_info
**pI
)
272 if (!control_cache_alloc_check(p_cache
)) {
273 HPI_DEBUG_LOG(VERBOSE
,
274 "control_cache_alloc_check() failed %d\n",
279 *pI
= p_cache
->p_info
[control_index
];
281 HPI_DEBUG_LOG(VERBOSE
, "Uncached Control %d\n",
285 HPI_DEBUG_LOG(VERBOSE
, "find_control() type %d\n",
286 (*pI
)->control_type
);
291 /* allow unified treatment of several string fields within struct */
292 #define HPICMN_PAD_OFS_AND_SIZE(m) {\
293 offsetof(struct hpi_control_cache_pad, m), \
294 sizeof(((struct hpi_control_cache_pad *)(NULL))->m) }
296 struct pad_ofs_size
{
298 unsigned int field_size
;
301 static struct pad_ofs_size pad_desc
[] = {
302 HPICMN_PAD_OFS_AND_SIZE(c_channel
), /* HPI_PAD_CHANNEL_NAME */
303 HPICMN_PAD_OFS_AND_SIZE(c_artist
), /* HPI_PAD_ARTIST */
304 HPICMN_PAD_OFS_AND_SIZE(c_title
), /* HPI_PAD_TITLE */
305 HPICMN_PAD_OFS_AND_SIZE(c_comment
), /* HPI_PAD_COMMENT */
308 /** CheckControlCache checks the cache and fills the struct hpi_response
309 * accordingly. It returns one if a cache hit occurred, zero otherwise.
311 short hpi_check_control_cache(struct hpi_control_cache
*p_cache
,
312 struct hpi_message
*phm
, struct hpi_response
*phr
)
315 struct hpi_control_cache_info
*pI
;
316 struct hpi_control_cache_single
*pC
;
317 struct hpi_control_cache_pad
*p_pad
;
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 /* pC is the default cached control strucure. May be cast to
329 something else in the following switch statement.
331 pC
= (struct hpi_control_cache_single
*)pI
;
332 p_pad
= (struct hpi_control_cache_pad
*)pI
;
334 switch (pI
->control_type
) {
336 case HPI_CONTROL_METER
:
337 if (phm
->u
.c
.attribute
== HPI_METER_PEAK
) {
338 phr
->u
.c
.an_log_value
[0] = pC
->u
.meter
.an_log_peak
[0];
339 phr
->u
.c
.an_log_value
[1] = pC
->u
.meter
.an_log_peak
[1];
340 } else if (phm
->u
.c
.attribute
== HPI_METER_RMS
) {
341 if (pC
->u
.meter
.an_logRMS
[0] ==
342 HPI_CACHE_INVALID_SHORT
) {
344 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE
;
345 phr
->u
.c
.an_log_value
[0] = HPI_METER_MINIMUM
;
346 phr
->u
.c
.an_log_value
[1] = HPI_METER_MINIMUM
;
348 phr
->u
.c
.an_log_value
[0] =
349 pC
->u
.meter
.an_logRMS
[0];
350 phr
->u
.c
.an_log_value
[1] =
351 pC
->u
.meter
.an_logRMS
[1];
356 case HPI_CONTROL_VOLUME
:
357 if (phm
->u
.c
.attribute
== HPI_VOLUME_GAIN
) {
358 phr
->u
.c
.an_log_value
[0] = pC
->u
.vol
.an_log
[0];
359 phr
->u
.c
.an_log_value
[1] = pC
->u
.vol
.an_log
[1];
360 } else if (phm
->u
.c
.attribute
== HPI_VOLUME_MUTE
) {
361 if (pC
->u
.vol
.flags
& HPI_VOLUME_FLAG_HAS_MUTE
) {
362 if (pC
->u
.vol
.flags
& HPI_VOLUME_FLAG_MUTED
)
364 HPI_BITMASK_ALL_CHANNELS
;
369 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE
;
376 case HPI_CONTROL_MULTIPLEXER
:
377 if (phm
->u
.c
.attribute
== HPI_MULTIPLEXER_SOURCE
) {
378 phr
->u
.c
.param1
= pC
->u
.mux
.source_node_type
;
379 phr
->u
.c
.param2
= pC
->u
.mux
.source_node_index
;
384 case HPI_CONTROL_CHANNEL_MODE
:
385 if (phm
->u
.c
.attribute
== HPI_CHANNEL_MODE_MODE
)
386 phr
->u
.c
.param1
= pC
->u
.mode
.mode
;
390 case HPI_CONTROL_LEVEL
:
391 if (phm
->u
.c
.attribute
== HPI_LEVEL_GAIN
) {
392 phr
->u
.c
.an_log_value
[0] = pC
->u
.level
.an_log
[0];
393 phr
->u
.c
.an_log_value
[1] = pC
->u
.level
.an_log
[1];
397 case HPI_CONTROL_TUNER
:
398 if (phm
->u
.c
.attribute
== HPI_TUNER_FREQ
)
399 phr
->u
.c
.param1
= pC
->u
.tuner
.freq_ink_hz
;
400 else if (phm
->u
.c
.attribute
== HPI_TUNER_BAND
)
401 phr
->u
.c
.param1
= pC
->u
.tuner
.band
;
402 else if (phm
->u
.c
.attribute
== HPI_TUNER_LEVEL_AVG
)
403 if (pC
->u
.tuner
.s_level_avg
==
404 HPI_CACHE_INVALID_SHORT
) {
405 phr
->u
.cu
.tuner
.s_level
= 0;
407 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE
;
409 phr
->u
.cu
.tuner
.s_level
=
410 pC
->u
.tuner
.s_level_avg
;
414 case HPI_CONTROL_AESEBU_RECEIVER
:
415 if (phm
->u
.c
.attribute
== HPI_AESEBURX_ERRORSTATUS
)
416 phr
->u
.c
.param1
= pC
->u
.aes3rx
.error_status
;
417 else if (phm
->u
.c
.attribute
== HPI_AESEBURX_FORMAT
)
418 phr
->u
.c
.param1
= pC
->u
.aes3rx
.format
;
422 case HPI_CONTROL_AESEBU_TRANSMITTER
:
423 if (phm
->u
.c
.attribute
== HPI_AESEBUTX_FORMAT
)
424 phr
->u
.c
.param1
= pC
->u
.aes3tx
.format
;
428 case HPI_CONTROL_TONEDETECTOR
:
429 if (phm
->u
.c
.attribute
== HPI_TONEDETECTOR_STATE
)
430 phr
->u
.c
.param1
= pC
->u
.tone
.state
;
434 case HPI_CONTROL_SILENCEDETECTOR
:
435 if (phm
->u
.c
.attribute
== HPI_SILENCEDETECTOR_STATE
) {
436 phr
->u
.c
.param1
= pC
->u
.silence
.state
;
440 case HPI_CONTROL_MICROPHONE
:
441 if (phm
->u
.c
.attribute
== HPI_MICROPHONE_PHANTOM_POWER
)
442 phr
->u
.c
.param1
= pC
->u
.microphone
.phantom_state
;
446 case HPI_CONTROL_SAMPLECLOCK
:
447 if (phm
->u
.c
.attribute
== HPI_SAMPLECLOCK_SOURCE
)
448 phr
->u
.c
.param1
= pC
->u
.clk
.source
;
449 else if (phm
->u
.c
.attribute
== HPI_SAMPLECLOCK_SOURCE_INDEX
) {
450 if (pC
->u
.clk
.source_index
==
451 HPI_CACHE_INVALID_UINT16
) {
454 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE
;
456 phr
->u
.c
.param1
= pC
->u
.clk
.source_index
;
457 } else if (phm
->u
.c
.attribute
== HPI_SAMPLECLOCK_SAMPLERATE
)
458 phr
->u
.c
.param1
= pC
->u
.clk
.sample_rate
;
462 case HPI_CONTROL_PAD
:{
463 struct hpi_control_cache_pad
*p_pad
;
464 p_pad
= (struct hpi_control_cache_pad
*)pI
;
466 if (!(p_pad
->field_valid_flags
& (1 <<
467 HPI_CTL_ATTR_INDEX(phm
->u
.c
.
470 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE
;
474 if (phm
->u
.c
.attribute
== HPI_PAD_PROGRAM_ID
)
475 phr
->u
.c
.param1
= p_pad
->pI
;
476 else if (phm
->u
.c
.attribute
== HPI_PAD_PROGRAM_TYPE
)
477 phr
->u
.c
.param1
= p_pad
->pTY
;
480 HPI_CTL_ATTR_INDEX(phm
->u
.c
.
482 unsigned int offset
= phm
->u
.c
.param1
;
483 unsigned int pad_string_len
, field_size
;
487 if (index
> ARRAY_SIZE(pad_desc
) - 1) {
489 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE
;
495 pad_desc
[index
].offset
;
496 field_size
= pad_desc
[index
].field_size
;
497 /* Ensure null terminator */
498 pad_string
[field_size
- 1] = 0;
500 pad_string_len
= strlen(pad_string
) + 1;
502 if (offset
> pad_string_len
) {
504 HPI_ERROR_INVALID_CONTROL_VALUE
;
508 tocopy
= pad_string_len
- offset
;
509 if (tocopy
> sizeof(phr
->u
.cu
.chars8
.sz_data
))
510 tocopy
= sizeof(phr
->u
.cu
.chars8
.
513 memcpy(phr
->u
.cu
.chars8
.sz_data
,
514 &pad_string
[offset
], tocopy
);
516 phr
->u
.cu
.chars8
.remaining_chars
=
517 pad_string_len
- offset
- tocopy
;
526 HPI_DEBUG_LOG(VERBOSE
, "%s Adap %d, Ctl %d, Type %d, Attr %d\n",
527 found
? "Cached" : "Uncached", phm
->adapter_index
,
528 pI
->control_index
, pI
->control_type
, phm
->u
.c
.attribute
);
532 sizeof(struct hpi_response_header
) +
533 sizeof(struct hpi_control_res
);
538 /** Updates the cache with Set values.
540 Only update if no error.
541 Volume and Level return the limited values in the response, so use these
542 Multiplexer does so use sent values
544 void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache
*p_cache
,
545 struct hpi_message
*phm
, struct hpi_response
*phr
)
547 struct hpi_control_cache_single
*pC
;
548 struct hpi_control_cache_info
*pI
;
553 if (!find_control(phm
->obj_index
, p_cache
, &pI
)) {
554 HPI_DEBUG_LOG(VERBOSE
,
555 "HPICMN find_control() failed for adap %d\n",
560 /* pC is the default cached control strucure.
561 May be cast to something else in the following switch statement.
563 pC
= (struct hpi_control_cache_single
*)pI
;
565 switch (pI
->control_type
) {
566 case HPI_CONTROL_VOLUME
:
567 if (phm
->u
.c
.attribute
== HPI_VOLUME_GAIN
) {
568 pC
->u
.vol
.an_log
[0] = phr
->u
.c
.an_log_value
[0];
569 pC
->u
.vol
.an_log
[1] = phr
->u
.c
.an_log_value
[1];
570 } else if (phm
->u
.c
.attribute
== HPI_VOLUME_MUTE
) {
572 pC
->u
.vol
.flags
|= HPI_VOLUME_FLAG_MUTED
;
574 pC
->u
.vol
.flags
&= ~HPI_VOLUME_FLAG_MUTED
;
577 case HPI_CONTROL_MULTIPLEXER
:
578 /* mux does not return its setting on Set command. */
579 if (phm
->u
.c
.attribute
== HPI_MULTIPLEXER_SOURCE
) {
580 pC
->u
.mux
.source_node_type
= (u16
)phm
->u
.c
.param1
;
581 pC
->u
.mux
.source_node_index
= (u16
)phm
->u
.c
.param2
;
584 case HPI_CONTROL_CHANNEL_MODE
:
585 /* mode does not return its setting on Set command. */
586 if (phm
->u
.c
.attribute
== HPI_CHANNEL_MODE_MODE
)
587 pC
->u
.mode
.mode
= (u16
)phm
->u
.c
.param1
;
589 case HPI_CONTROL_LEVEL
:
590 if (phm
->u
.c
.attribute
== HPI_LEVEL_GAIN
) {
591 pC
->u
.vol
.an_log
[0] = phr
->u
.c
.an_log_value
[0];
592 pC
->u
.vol
.an_log
[1] = phr
->u
.c
.an_log_value
[1];
595 case HPI_CONTROL_MICROPHONE
:
596 if (phm
->u
.c
.attribute
== HPI_MICROPHONE_PHANTOM_POWER
)
597 pC
->u
.microphone
.phantom_state
= (u16
)phm
->u
.c
.param1
;
599 case HPI_CONTROL_AESEBU_TRANSMITTER
:
600 if (phm
->u
.c
.attribute
== HPI_AESEBUTX_FORMAT
)
601 pC
->u
.aes3tx
.format
= phm
->u
.c
.param1
;
603 case HPI_CONTROL_AESEBU_RECEIVER
:
604 if (phm
->u
.c
.attribute
== HPI_AESEBURX_FORMAT
)
605 pC
->u
.aes3rx
.format
= phm
->u
.c
.param1
;
607 case HPI_CONTROL_SAMPLECLOCK
:
608 if (phm
->u
.c
.attribute
== HPI_SAMPLECLOCK_SOURCE
)
609 pC
->u
.clk
.source
= (u16
)phm
->u
.c
.param1
;
610 else if (phm
->u
.c
.attribute
== HPI_SAMPLECLOCK_SOURCE_INDEX
)
611 pC
->u
.clk
.source_index
= (u16
)phm
->u
.c
.param1
;
612 else if (phm
->u
.c
.attribute
== HPI_SAMPLECLOCK_SAMPLERATE
)
613 pC
->u
.clk
.sample_rate
= phm
->u
.c
.param1
;
620 struct hpi_control_cache
*hpi_alloc_control_cache(const u32 control_count
,
621 const u32 size_in_bytes
, u8
*p_dsp_control_buffer
)
623 struct hpi_control_cache
*p_cache
=
624 kmalloc(sizeof(*p_cache
), GFP_KERNEL
);
629 kmalloc(sizeof(*p_cache
->p_info
) * control_count
, GFP_KERNEL
);
630 if (!p_cache
->p_info
) {
634 memset(p_cache
->p_info
, 0, sizeof(*p_cache
->p_info
) * control_count
);
635 p_cache
->cache_size_in_bytes
= size_in_bytes
;
636 p_cache
->control_count
= control_count
;
637 p_cache
->p_cache
= p_dsp_control_buffer
;
642 void hpi_free_control_cache(struct hpi_control_cache
*p_cache
)
645 kfree(p_cache
->p_info
);
650 static void subsys_message(struct hpi_message
*phm
, struct hpi_response
*phr
)
652 hpi_init_response(phr
, HPI_OBJ_SUBSYSTEM
, phm
->function
, 0);
654 switch (phm
->function
) {
655 case HPI_SUBSYS_OPEN
:
656 case HPI_SUBSYS_CLOSE
:
657 case HPI_SUBSYS_DRIVER_UNLOAD
:
659 case HPI_SUBSYS_DRIVER_LOAD
:
661 hpios_alistlock_init(&adapters
);
663 case HPI_SUBSYS_GET_ADAPTER
:
664 subsys_get_adapter(phm
, phr
);
666 case HPI_SUBSYS_GET_NUM_ADAPTERS
:
667 phr
->u
.s
.num_adapters
= adapters
.gw_num_adapters
;
669 case HPI_SUBSYS_CREATE_ADAPTER
:
670 case HPI_SUBSYS_DELETE_ADAPTER
:
673 phr
->error
= HPI_ERROR_INVALID_FUNC
;
678 void HPI_COMMON(struct hpi_message
*phm
, struct hpi_response
*phr
)
681 case HPI_TYPE_MESSAGE
:
682 switch (phm
->object
) {
683 case HPI_OBJ_SUBSYSTEM
:
684 subsys_message(phm
, phr
);
690 phr
->error
= HPI_ERROR_INVALID_TYPE
;