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
;
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 struct hpi_control_cache_pad
*p_pad
;
320 if (!find_control(phm
->obj_index
, p_cache
, &pI
)) {
321 HPI_DEBUG_LOG(VERBOSE
,
322 "HPICMN find_control() failed for adap %d\n",
329 /* pC is the default cached control strucure. May be cast to
330 something else in the following switch statement.
332 pC
= (struct hpi_control_cache_single
*)pI
;
333 p_pad
= (struct hpi_control_cache_pad
*)pI
;
335 switch (pI
->control_type
) {
337 case HPI_CONTROL_METER
:
338 if (phm
->u
.c
.attribute
== HPI_METER_PEAK
) {
339 phr
->u
.c
.an_log_value
[0] = pC
->u
.meter
.an_log_peak
[0];
340 phr
->u
.c
.an_log_value
[1] = pC
->u
.meter
.an_log_peak
[1];
341 } else if (phm
->u
.c
.attribute
== HPI_METER_RMS
) {
342 if (pC
->u
.meter
.an_logRMS
[0] ==
343 HPI_CACHE_INVALID_SHORT
) {
345 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE
;
346 phr
->u
.c
.an_log_value
[0] = HPI_METER_MINIMUM
;
347 phr
->u
.c
.an_log_value
[1] = HPI_METER_MINIMUM
;
349 phr
->u
.c
.an_log_value
[0] =
350 pC
->u
.meter
.an_logRMS
[0];
351 phr
->u
.c
.an_log_value
[1] =
352 pC
->u
.meter
.an_logRMS
[1];
357 case HPI_CONTROL_VOLUME
:
358 if (phm
->u
.c
.attribute
== HPI_VOLUME_GAIN
) {
359 phr
->u
.c
.an_log_value
[0] = pC
->u
.vol
.an_log
[0];
360 phr
->u
.c
.an_log_value
[1] = pC
->u
.vol
.an_log
[1];
361 } else if (phm
->u
.c
.attribute
== HPI_VOLUME_MUTE
) {
362 if (pC
->u
.vol
.flags
& HPI_VOLUME_FLAG_HAS_MUTE
) {
363 if (pC
->u
.vol
.flags
& HPI_VOLUME_FLAG_MUTED
)
365 HPI_BITMASK_ALL_CHANNELS
;
370 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE
;
377 case HPI_CONTROL_MULTIPLEXER
:
378 if (phm
->u
.c
.attribute
== HPI_MULTIPLEXER_SOURCE
) {
379 phr
->u
.c
.param1
= pC
->u
.mux
.source_node_type
;
380 phr
->u
.c
.param2
= pC
->u
.mux
.source_node_index
;
385 case HPI_CONTROL_CHANNEL_MODE
:
386 if (phm
->u
.c
.attribute
== HPI_CHANNEL_MODE_MODE
)
387 phr
->u
.c
.param1
= pC
->u
.mode
.mode
;
391 case HPI_CONTROL_LEVEL
:
392 if (phm
->u
.c
.attribute
== HPI_LEVEL_GAIN
) {
393 phr
->u
.c
.an_log_value
[0] = pC
->u
.level
.an_log
[0];
394 phr
->u
.c
.an_log_value
[1] = pC
->u
.level
.an_log
[1];
398 case HPI_CONTROL_TUNER
:
399 if (phm
->u
.c
.attribute
== HPI_TUNER_FREQ
)
400 phr
->u
.c
.param1
= pC
->u
.tuner
.freq_ink_hz
;
401 else if (phm
->u
.c
.attribute
== HPI_TUNER_BAND
)
402 phr
->u
.c
.param1
= pC
->u
.tuner
.band
;
403 else if (phm
->u
.c
.attribute
== HPI_TUNER_LEVEL_AVG
)
404 if (pC
->u
.tuner
.s_level_avg
==
405 HPI_CACHE_INVALID_SHORT
) {
406 phr
->u
.cu
.tuner
.s_level
= 0;
408 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE
;
410 phr
->u
.cu
.tuner
.s_level
=
411 pC
->u
.tuner
.s_level_avg
;
415 case HPI_CONTROL_AESEBU_RECEIVER
:
416 if (phm
->u
.c
.attribute
== HPI_AESEBURX_ERRORSTATUS
)
417 phr
->u
.c
.param1
= pC
->u
.aes3rx
.error_status
;
418 else if (phm
->u
.c
.attribute
== HPI_AESEBURX_FORMAT
)
419 phr
->u
.c
.param1
= pC
->u
.aes3rx
.format
;
423 case HPI_CONTROL_AESEBU_TRANSMITTER
:
424 if (phm
->u
.c
.attribute
== HPI_AESEBUTX_FORMAT
)
425 phr
->u
.c
.param1
= pC
->u
.aes3tx
.format
;
429 case HPI_CONTROL_TONEDETECTOR
:
430 if (phm
->u
.c
.attribute
== HPI_TONEDETECTOR_STATE
)
431 phr
->u
.c
.param1
= pC
->u
.tone
.state
;
435 case HPI_CONTROL_SILENCEDETECTOR
:
436 if (phm
->u
.c
.attribute
== HPI_SILENCEDETECTOR_STATE
) {
437 phr
->u
.c
.param1
= pC
->u
.silence
.state
;
441 case HPI_CONTROL_MICROPHONE
:
442 if (phm
->u
.c
.attribute
== HPI_MICROPHONE_PHANTOM_POWER
)
443 phr
->u
.c
.param1
= pC
->u
.microphone
.phantom_state
;
447 case HPI_CONTROL_SAMPLECLOCK
:
448 if (phm
->u
.c
.attribute
== HPI_SAMPLECLOCK_SOURCE
)
449 phr
->u
.c
.param1
= pC
->u
.clk
.source
;
450 else if (phm
->u
.c
.attribute
== HPI_SAMPLECLOCK_SOURCE_INDEX
) {
451 if (pC
->u
.clk
.source_index
==
452 HPI_CACHE_INVALID_UINT16
) {
455 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE
;
457 phr
->u
.c
.param1
= pC
->u
.clk
.source_index
;
458 } else if (phm
->u
.c
.attribute
== HPI_SAMPLECLOCK_SAMPLERATE
)
459 phr
->u
.c
.param1
= pC
->u
.clk
.sample_rate
;
463 case HPI_CONTROL_PAD
:{
464 struct hpi_control_cache_pad
*p_pad
;
465 p_pad
= (struct hpi_control_cache_pad
*)pI
;
467 if (!(p_pad
->field_valid_flags
& (1 <<
468 HPI_CTL_ATTR_INDEX(phm
->u
.c
.
471 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE
;
475 if (phm
->u
.c
.attribute
== HPI_PAD_PROGRAM_ID
)
476 phr
->u
.c
.param1
= p_pad
->pI
;
477 else if (phm
->u
.c
.attribute
== HPI_PAD_PROGRAM_TYPE
)
478 phr
->u
.c
.param1
= p_pad
->pTY
;
481 HPI_CTL_ATTR_INDEX(phm
->u
.c
.
483 unsigned int offset
= phm
->u
.c
.param1
;
484 unsigned int pad_string_len
, field_size
;
488 if (index
> ARRAY_SIZE(pad_desc
) - 1) {
490 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE
;
496 pad_desc
[index
].offset
;
497 field_size
= pad_desc
[index
].field_size
;
498 /* Ensure null terminator */
499 pad_string
[field_size
- 1] = 0;
501 pad_string_len
= strlen(pad_string
) + 1;
503 if (offset
> pad_string_len
) {
505 HPI_ERROR_INVALID_CONTROL_VALUE
;
509 tocopy
= pad_string_len
- offset
;
510 if (tocopy
> sizeof(phr
->u
.cu
.chars8
.sz_data
))
511 tocopy
= sizeof(phr
->u
.cu
.chars8
.
514 memcpy(phr
->u
.cu
.chars8
.sz_data
,
515 &pad_string
[offset
], tocopy
);
517 phr
->u
.cu
.chars8
.remaining_chars
=
518 pad_string_len
- offset
- tocopy
;
527 HPI_DEBUG_LOG(VERBOSE
, "%s Adap %d, Ctl %d, Type %d, Attr %d\n",
528 found
? "Cached" : "Uncached", phm
->adapter_index
,
529 pI
->control_index
, pI
->control_type
, phm
->u
.c
.attribute
);
533 sizeof(struct hpi_response_header
) +
534 sizeof(struct hpi_control_res
);
539 /** Updates the cache with Set values.
541 Only update if no error.
542 Volume and Level return the limited values in the response, so use these
543 Multiplexer does so use sent values
545 void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache
*p_cache
,
546 struct hpi_message
*phm
, struct hpi_response
*phr
)
548 struct hpi_control_cache_single
*pC
;
549 struct hpi_control_cache_info
*pI
;
554 if (!find_control(phm
->obj_index
, p_cache
, &pI
)) {
555 HPI_DEBUG_LOG(VERBOSE
,
556 "HPICMN find_control() failed for adap %d\n",
561 /* pC is the default cached control strucure.
562 May be cast to something else in the following switch statement.
564 pC
= (struct hpi_control_cache_single
*)pI
;
566 switch (pI
->control_type
) {
567 case HPI_CONTROL_VOLUME
:
568 if (phm
->u
.c
.attribute
== HPI_VOLUME_GAIN
) {
569 pC
->u
.vol
.an_log
[0] = phr
->u
.c
.an_log_value
[0];
570 pC
->u
.vol
.an_log
[1] = phr
->u
.c
.an_log_value
[1];
571 } else if (phm
->u
.c
.attribute
== HPI_VOLUME_MUTE
) {
573 pC
->u
.vol
.flags
|= HPI_VOLUME_FLAG_MUTED
;
575 pC
->u
.vol
.flags
&= ~HPI_VOLUME_FLAG_MUTED
;
578 case HPI_CONTROL_MULTIPLEXER
:
579 /* mux does not return its setting on Set command. */
580 if (phm
->u
.c
.attribute
== HPI_MULTIPLEXER_SOURCE
) {
581 pC
->u
.mux
.source_node_type
= (u16
)phm
->u
.c
.param1
;
582 pC
->u
.mux
.source_node_index
= (u16
)phm
->u
.c
.param2
;
585 case HPI_CONTROL_CHANNEL_MODE
:
586 /* mode does not return its setting on Set command. */
587 if (phm
->u
.c
.attribute
== HPI_CHANNEL_MODE_MODE
)
588 pC
->u
.mode
.mode
= (u16
)phm
->u
.c
.param1
;
590 case HPI_CONTROL_LEVEL
:
591 if (phm
->u
.c
.attribute
== HPI_LEVEL_GAIN
) {
592 pC
->u
.vol
.an_log
[0] = phr
->u
.c
.an_log_value
[0];
593 pC
->u
.vol
.an_log
[1] = phr
->u
.c
.an_log_value
[1];
596 case HPI_CONTROL_MICROPHONE
:
597 if (phm
->u
.c
.attribute
== HPI_MICROPHONE_PHANTOM_POWER
)
598 pC
->u
.microphone
.phantom_state
= (u16
)phm
->u
.c
.param1
;
600 case HPI_CONTROL_AESEBU_TRANSMITTER
:
601 if (phm
->u
.c
.attribute
== HPI_AESEBUTX_FORMAT
)
602 pC
->u
.aes3tx
.format
= phm
->u
.c
.param1
;
604 case HPI_CONTROL_AESEBU_RECEIVER
:
605 if (phm
->u
.c
.attribute
== HPI_AESEBURX_FORMAT
)
606 pC
->u
.aes3rx
.format
= phm
->u
.c
.param1
;
608 case HPI_CONTROL_SAMPLECLOCK
:
609 if (phm
->u
.c
.attribute
== HPI_SAMPLECLOCK_SOURCE
)
610 pC
->u
.clk
.source
= (u16
)phm
->u
.c
.param1
;
611 else if (phm
->u
.c
.attribute
== HPI_SAMPLECLOCK_SOURCE_INDEX
)
612 pC
->u
.clk
.source_index
= (u16
)phm
->u
.c
.param1
;
613 else if (phm
->u
.c
.attribute
== HPI_SAMPLECLOCK_SAMPLERATE
)
614 pC
->u
.clk
.sample_rate
= phm
->u
.c
.param1
;
621 /** Allocate control cache.
623 \return Cache pointer, or NULL if allocation fails.
625 struct hpi_control_cache
*hpi_alloc_control_cache(const u32 control_count
,
626 const u32 size_in_bytes
, u8
*p_dsp_control_buffer
)
628 struct hpi_control_cache
*p_cache
=
629 kmalloc(sizeof(*p_cache
), GFP_KERNEL
);
634 kmalloc(sizeof(*p_cache
->p_info
) * control_count
, GFP_KERNEL
);
635 if (!p_cache
->p_info
) {
639 memset(p_cache
->p_info
, 0, sizeof(*p_cache
->p_info
) * control_count
);
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_MESSAGE
:
686 switch (phm
->object
) {
687 case HPI_OBJ_SUBSYSTEM
:
688 subsys_message(phm
, phr
);
694 phr
->error
= HPI_ERROR_INVALID_TYPE
;