1 /******************************************************************************
3 AudioScience HPI driver
4 Copyright (C) 1997-2014 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->type); */
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
].type
) {
82 for (a
= HPI_MAX_ADAPTERS
- 1; a
>= 0; a
--) {
83 if (!adapters
.adapter
[a
].type
) {
84 HPI_DEBUG_LOG(WARNING
,
85 "ASI%X duplicate index %d moved to %d\n",
86 pao
->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
)
108 HPI_DEBUG_LOG(ERROR
, "removing null adapter?\n");
112 hpios_alistlock_lock(&adapters
);
113 if (adapters
.adapter
[pao
->index
].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
->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
].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
].type
;
179 phr
->u
.s
.adapter_index
= 0;
180 phr
->u
.s
.adapter_type
= 0;
181 phr
->error
= HPI_ERROR_INVALID_OBJ_INDEX
;
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
];
209 u16 control_index
= info
->control_index
;
211 if (control_index
>= pC
->control_count
) {
213 "adap %d control index %d out of range, cache not ready?\n",
214 pC
->adap_idx
, control_index
);
218 if (!info
->size_in32bit_words
) {
221 "adap %d cache not ready?\n",
225 /* The cache is invalid.
226 * Minimum valid entry size is
227 * sizeof(struct hpi_control_cache_info)
230 "adap %d zero size cache entry %d\n",
235 if (info
->control_type
) {
236 pC
->p_info
[control_index
] = info
;
238 } else { /* dummy cache entry */
239 pC
->p_info
[control_index
] = NULL
;
242 byte_count
+= info
->size_in32bit_words
* 4;
244 HPI_DEBUG_LOG(VERBOSE
,
245 "cached %d, pinfo %p index %d type %d size %d\n",
246 cached
, pC
->p_info
[info
->control_index
],
247 info
->control_index
, info
->control_type
,
248 info
->size_in32bit_words
);
250 /* quit loop early if whole cache has been scanned.
251 * dwControlCount is the maximum possible entries
252 * but some may be absent from the cache
254 if (byte_count
>= pC
->cache_size_in_bytes
)
256 /* have seen last control index */
257 if (info
->control_index
== pC
->control_count
- 1)
261 if (byte_count
!= pC
->cache_size_in_bytes
)
262 HPI_DEBUG_LOG(WARNING
,
263 "adap %d bytecount %d != cache size %d\n",
264 pC
->adap_idx
, byte_count
,
265 pC
->cache_size_in_bytes
);
268 "adap %d cache good, bytecount == cache size = %d\n",
269 pC
->adap_idx
, byte_count
);
271 pC
->init
= (u16
)cached
;
278 static short find_control(u16 control_index
,
279 struct hpi_control_cache
*p_cache
, struct hpi_control_cache_info
**pI
)
281 if (!control_cache_alloc_check(p_cache
)) {
282 HPI_DEBUG_LOG(VERBOSE
,
283 "control_cache_alloc_check() failed %d\n",
288 *pI
= p_cache
->p_info
[control_index
];
290 HPI_DEBUG_LOG(VERBOSE
, "Uncached Control %d\n",
294 HPI_DEBUG_LOG(VERBOSE
, "find_control() type %d\n",
295 (*pI
)->control_type
);
300 /* allow unified treatment of several string fields within struct */
301 #define HPICMN_PAD_OFS_AND_SIZE(m) {\
302 offsetof(struct hpi_control_cache_pad, m), \
303 sizeof(((struct hpi_control_cache_pad *)(NULL))->m) }
305 struct pad_ofs_size
{
307 unsigned int field_size
;
310 static const struct pad_ofs_size pad_desc
[] = {
311 HPICMN_PAD_OFS_AND_SIZE(c_channel
), /* HPI_PAD_CHANNEL_NAME */
312 HPICMN_PAD_OFS_AND_SIZE(c_artist
), /* HPI_PAD_ARTIST */
313 HPICMN_PAD_OFS_AND_SIZE(c_title
), /* HPI_PAD_TITLE */
314 HPICMN_PAD_OFS_AND_SIZE(c_comment
), /* HPI_PAD_COMMENT */
317 /** CheckControlCache checks the cache and fills the struct hpi_response
318 * accordingly. It returns one if a cache hit occurred, zero otherwise.
320 short hpi_check_control_cache_single(struct hpi_control_cache_single
*pC
,
321 struct hpi_message
*phm
, struct hpi_response
*phr
)
323 size_t response_size
;
326 /* set the default response size */
328 sizeof(struct hpi_response_header
) +
329 sizeof(struct hpi_control_res
);
331 switch (pC
->u
.i
.control_type
) {
333 case HPI_CONTROL_METER
:
334 if (phm
->u
.c
.attribute
== HPI_METER_PEAK
) {
335 phr
->u
.c
.an_log_value
[0] = pC
->u
.meter
.an_log_peak
[0];
336 phr
->u
.c
.an_log_value
[1] = pC
->u
.meter
.an_log_peak
[1];
337 } else if (phm
->u
.c
.attribute
== HPI_METER_RMS
) {
338 if (pC
->u
.meter
.an_logRMS
[0] ==
339 HPI_CACHE_INVALID_SHORT
) {
341 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE
;
342 phr
->u
.c
.an_log_value
[0] = HPI_METER_MINIMUM
;
343 phr
->u
.c
.an_log_value
[1] = HPI_METER_MINIMUM
;
345 phr
->u
.c
.an_log_value
[0] =
346 pC
->u
.meter
.an_logRMS
[0];
347 phr
->u
.c
.an_log_value
[1] =
348 pC
->u
.meter
.an_logRMS
[1];
353 case HPI_CONTROL_VOLUME
:
354 if (phm
->u
.c
.attribute
== HPI_VOLUME_GAIN
) {
355 phr
->u
.c
.an_log_value
[0] = pC
->u
.vol
.an_log
[0];
356 phr
->u
.c
.an_log_value
[1] = pC
->u
.vol
.an_log
[1];
357 } else if (phm
->u
.c
.attribute
== HPI_VOLUME_MUTE
) {
358 if (pC
->u
.vol
.flags
& HPI_VOLUME_FLAG_HAS_MUTE
) {
359 if (pC
->u
.vol
.flags
& HPI_VOLUME_FLAG_MUTED
)
361 HPI_BITMASK_ALL_CHANNELS
;
366 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE
;
373 case HPI_CONTROL_MULTIPLEXER
:
374 if (phm
->u
.c
.attribute
== HPI_MULTIPLEXER_SOURCE
) {
375 phr
->u
.c
.param1
= pC
->u
.mux
.source_node_type
;
376 phr
->u
.c
.param2
= pC
->u
.mux
.source_node_index
;
381 case HPI_CONTROL_CHANNEL_MODE
:
382 if (phm
->u
.c
.attribute
== HPI_CHANNEL_MODE_MODE
)
383 phr
->u
.c
.param1
= pC
->u
.mode
.mode
;
387 case HPI_CONTROL_LEVEL
:
388 if (phm
->u
.c
.attribute
== HPI_LEVEL_GAIN
) {
389 phr
->u
.c
.an_log_value
[0] = pC
->u
.level
.an_log
[0];
390 phr
->u
.c
.an_log_value
[1] = pC
->u
.level
.an_log
[1];
394 case HPI_CONTROL_TUNER
:
395 if (phm
->u
.c
.attribute
== HPI_TUNER_FREQ
)
396 phr
->u
.c
.param1
= pC
->u
.tuner
.freq_ink_hz
;
397 else if (phm
->u
.c
.attribute
== HPI_TUNER_BAND
)
398 phr
->u
.c
.param1
= pC
->u
.tuner
.band
;
399 else if (phm
->u
.c
.attribute
== HPI_TUNER_LEVEL_AVG
)
400 if (pC
->u
.tuner
.s_level_avg
==
401 HPI_CACHE_INVALID_SHORT
) {
402 phr
->u
.cu
.tuner
.s_level
= 0;
404 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE
;
406 phr
->u
.cu
.tuner
.s_level
=
407 pC
->u
.tuner
.s_level_avg
;
411 case HPI_CONTROL_AESEBU_RECEIVER
:
412 if (phm
->u
.c
.attribute
== HPI_AESEBURX_ERRORSTATUS
)
413 phr
->u
.c
.param1
= pC
->u
.aes3rx
.error_status
;
414 else if (phm
->u
.c
.attribute
== HPI_AESEBURX_FORMAT
)
415 phr
->u
.c
.param1
= pC
->u
.aes3rx
.format
;
419 case HPI_CONTROL_AESEBU_TRANSMITTER
:
420 if (phm
->u
.c
.attribute
== HPI_AESEBUTX_FORMAT
)
421 phr
->u
.c
.param1
= pC
->u
.aes3tx
.format
;
425 case HPI_CONTROL_TONEDETECTOR
:
426 if (phm
->u
.c
.attribute
== HPI_TONEDETECTOR_STATE
)
427 phr
->u
.c
.param1
= pC
->u
.tone
.state
;
431 case HPI_CONTROL_SILENCEDETECTOR
:
432 if (phm
->u
.c
.attribute
== HPI_SILENCEDETECTOR_STATE
) {
433 phr
->u
.c
.param1
= pC
->u
.silence
.state
;
437 case HPI_CONTROL_MICROPHONE
:
438 if (phm
->u
.c
.attribute
== HPI_MICROPHONE_PHANTOM_POWER
)
439 phr
->u
.c
.param1
= pC
->u
.microphone
.phantom_state
;
443 case HPI_CONTROL_SAMPLECLOCK
:
444 if (phm
->u
.c
.attribute
== HPI_SAMPLECLOCK_SOURCE
)
445 phr
->u
.c
.param1
= pC
->u
.clk
.source
;
446 else if (phm
->u
.c
.attribute
== HPI_SAMPLECLOCK_SOURCE_INDEX
) {
447 if (pC
->u
.clk
.source_index
==
448 HPI_CACHE_INVALID_UINT16
) {
451 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE
;
453 phr
->u
.c
.param1
= pC
->u
.clk
.source_index
;
454 } else if (phm
->u
.c
.attribute
== HPI_SAMPLECLOCK_SAMPLERATE
)
455 phr
->u
.c
.param1
= pC
->u
.clk
.sample_rate
;
459 case HPI_CONTROL_PAD
:{
460 struct hpi_control_cache_pad
*p_pad
;
461 p_pad
= (struct hpi_control_cache_pad
*)pC
;
463 if (!(p_pad
->field_valid_flags
& (1 <<
464 HPI_CTL_ATTR_INDEX(phm
->u
.c
.
467 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE
;
471 if (phm
->u
.c
.attribute
== HPI_PAD_PROGRAM_ID
)
472 phr
->u
.c
.param1
= p_pad
->pI
;
473 else if (phm
->u
.c
.attribute
== HPI_PAD_PROGRAM_TYPE
)
474 phr
->u
.c
.param1
= p_pad
->pTY
;
477 HPI_CTL_ATTR_INDEX(phm
->u
.c
.
479 unsigned int offset
= phm
->u
.c
.param1
;
480 unsigned int pad_string_len
, field_size
;
484 if (index
> ARRAY_SIZE(pad_desc
) - 1) {
486 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE
;
492 pad_desc
[index
].offset
;
493 field_size
= pad_desc
[index
].field_size
;
494 /* Ensure null terminator */
495 pad_string
[field_size
- 1] = 0;
497 pad_string_len
= strlen(pad_string
) + 1;
499 if (offset
> pad_string_len
) {
501 HPI_ERROR_INVALID_CONTROL_VALUE
;
505 tocopy
= pad_string_len
- offset
;
506 if (tocopy
> sizeof(phr
->u
.cu
.chars8
.sz_data
))
507 tocopy
= sizeof(phr
->u
.cu
.chars8
.
510 memcpy(phr
->u
.cu
.chars8
.sz_data
,
511 &pad_string
[offset
], tocopy
);
513 phr
->u
.cu
.chars8
.remaining_chars
=
514 pad_string_len
- offset
- tocopy
;
523 HPI_DEBUG_LOG(VERBOSE
, "%s Adap %d, Ctl %d, Type %d, Attr %d\n",
524 found
? "Cached" : "Uncached", phm
->adapter_index
,
525 pC
->u
.i
.control_index
, pC
->u
.i
.control_type
,
529 phr
->size
= (u16
)response_size
;
530 phr
->type
= HPI_TYPE_RESPONSE
;
531 phr
->object
= phm
->object
;
532 phr
->function
= phm
->function
;
538 short hpi_check_control_cache(struct hpi_control_cache
*p_cache
,
539 struct hpi_message
*phm
, struct hpi_response
*phr
)
541 struct hpi_control_cache_info
*pI
;
543 if (!find_control(phm
->obj_index
, p_cache
, &pI
)) {
544 HPI_DEBUG_LOG(VERBOSE
,
545 "HPICMN find_control() failed for adap %d\n",
551 phr
->specific_error
= 0;
554 return hpi_check_control_cache_single((struct hpi_control_cache_single
558 /** Updates the cache with Set values.
560 Only update if no error.
561 Volume and Level return the limited values in the response, so use these
562 Multiplexer does so use sent values
564 void hpi_cmn_control_cache_sync_to_msg_single(struct hpi_control_cache_single
565 *pC
, struct hpi_message
*phm
, struct hpi_response
*phr
)
567 switch (pC
->u
.i
.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 void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache
*p_cache
,
623 struct hpi_message
*phm
, struct hpi_response
*phr
)
625 struct hpi_control_cache_single
*pC
;
626 struct hpi_control_cache_info
*pI
;
631 if (!find_control(phm
->obj_index
, p_cache
, &pI
)) {
632 HPI_DEBUG_LOG(VERBOSE
,
633 "HPICMN find_control() failed for adap %d\n",
638 /* pC is the default cached control strucure.
639 May be cast to something else in the following switch statement.
641 pC
= (struct hpi_control_cache_single
*)pI
;
643 hpi_cmn_control_cache_sync_to_msg_single(pC
, phm
, phr
);
646 /** Allocate control cache.
648 \return Cache pointer, or NULL if allocation fails.
650 struct hpi_control_cache
*hpi_alloc_control_cache(const u32 control_count
,
651 const u32 size_in_bytes
, u8
*p_dsp_control_buffer
)
653 struct hpi_control_cache
*p_cache
=
654 kmalloc(sizeof(*p_cache
), GFP_KERNEL
);
659 kcalloc(control_count
, sizeof(*p_cache
->p_info
), GFP_KERNEL
);
660 if (!p_cache
->p_info
) {
665 p_cache
->cache_size_in_bytes
= size_in_bytes
;
666 p_cache
->control_count
= control_count
;
667 p_cache
->p_cache
= p_dsp_control_buffer
;
672 void hpi_free_control_cache(struct hpi_control_cache
*p_cache
)
675 kfree(p_cache
->p_info
);
680 static void subsys_message(struct hpi_message
*phm
, struct hpi_response
*phr
)
682 hpi_init_response(phr
, HPI_OBJ_SUBSYSTEM
, phm
->function
, 0);
684 switch (phm
->function
) {
685 case HPI_SUBSYS_OPEN
:
686 case HPI_SUBSYS_CLOSE
:
687 case HPI_SUBSYS_DRIVER_UNLOAD
:
689 case HPI_SUBSYS_DRIVER_LOAD
:
691 hpios_alistlock_init(&adapters
);
693 case HPI_SUBSYS_GET_ADAPTER
:
694 subsys_get_adapter(phm
, phr
);
696 case HPI_SUBSYS_GET_NUM_ADAPTERS
:
697 phr
->u
.s
.num_adapters
= adapters
.gw_num_adapters
;
699 case HPI_SUBSYS_CREATE_ADAPTER
:
702 phr
->error
= HPI_ERROR_INVALID_FUNC
;
707 void HPI_COMMON(struct hpi_message
*phm
, struct hpi_response
*phr
)
710 case HPI_TYPE_REQUEST
:
711 switch (phm
->object
) {
712 case HPI_OBJ_SUBSYSTEM
:
713 subsys_message(phm
, phr
);
719 phr
->error
= HPI_ERROR_INVALID_TYPE
;