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 retval = HPI_DUPLICATE_ADAPTER_NUMBER;
86 adapters.adapter[pao->index] = *pao;
87 hpios_dsplock_init(&adapters.adapter[pao->index]);
88 adapters.gw_num_adapters++;
91 hpios_alistlock_unlock(&adapters);
95 void hpi_delete_adapter(struct hpi_adapter_obj *pao)
97 if (!pao->adapter_type) {
98 HPI_DEBUG_LOG(ERROR, "removing null adapter?\n");
102 hpios_alistlock_lock(&adapters);
103 if (adapters.adapter[pao->index].adapter_type)
104 adapters.gw_num_adapters--;
105 memset(&adapters.adapter[pao->index], 0, sizeof(adapters.adapter[0]));
106 hpios_alistlock_unlock(&adapters);
110 * FindAdapter returns a pointer to the struct hpi_adapter_obj with
111 * index wAdapterIndex in an HPI_ADAPTERS_LIST structure.
114 struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index)
116 struct hpi_adapter_obj *pao = NULL;
118 if (adapter_index >= HPI_MAX_ADAPTERS) {
119 HPI_DEBUG_LOG(VERBOSE, "find_adapter invalid index %d\n",
124 pao = &adapters.adapter[adapter_index];
125 if (pao->adapter_type != 0) {
127 HPI_DEBUG_LOG(VERBOSE, "Found adapter index %d\n",
133 HPI_DEBUG_LOG(VERBOSE, "No adapter index %d\n",
142 * wipe an HPI_ADAPTERS_LIST structure.
145 static void wipe_adapter_list(void)
147 memset(&adapters, 0, sizeof(adapters));
150 static void subsys_get_adapter(struct hpi_message *phm,
151 struct hpi_response *phr)
153 int count = phm->obj_index;
156 /* find the nCount'th nonzero adapter in array */
157 for (index = 0; index < HPI_MAX_ADAPTERS; index++) {
158 if (adapters.adapter[index].adapter_type) {
165 if (index < HPI_MAX_ADAPTERS) {
166 phr->u.s.adapter_index = adapters.adapter[index].index;
167 phr->u.s.adapter_type = adapters.adapter[index].adapter_type;
169 phr->u.s.adapter_index = 0;
170 phr->u.s.adapter_type = 0;
171 phr->error = HPI_ERROR_BAD_ADAPTER_NUMBER;
175 static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
188 if (pC->control_count && pC->cache_size_in_bytes) {
189 char *p_master_cache;
190 unsigned int byte_count = 0;
192 p_master_cache = (char *)pC->p_cache;
193 HPI_DEBUG_LOG(DEBUG, "check %d controls\n",
195 for (i = 0; i < pC->control_count; i++) {
196 struct hpi_control_cache_info *info =
197 (struct hpi_control_cache_info *)
198 &p_master_cache[byte_count];
200 if (!info->size_in32bit_words) {
203 "adap %d cache not ready?\n",
207 /* The cache is invalid.
208 * Minimum valid entry size is
209 * sizeof(struct hpi_control_cache_info)
212 "adap %d zero size cache entry %d\n",
217 if (info->control_type) {
218 pC->p_info[info->control_index] = info;
220 } else /* dummy cache entry */
221 pC->p_info[info->control_index] = NULL;
223 byte_count += info->size_in32bit_words * 4;
225 HPI_DEBUG_LOG(VERBOSE,
226 "cached %d, pinfo %p index %d type %d size %d\n",
227 cached, pC->p_info[info->control_index],
228 info->control_index, info->control_type,
229 info->size_in32bit_words);
231 /* quit loop early if whole cache has been scanned.
232 * dwControlCount is the maximum possible entries
233 * but some may be absent from the cache
235 if (byte_count >= pC->cache_size_in_bytes)
237 /* have seen last control index */
238 if (info->control_index == pC->control_count - 1)
242 if (byte_count != pC->cache_size_in_bytes)
243 HPI_DEBUG_LOG(WARNING,
244 "adap %d bytecount %d != cache size %d\n",
245 pC->adap_idx, byte_count,
246 pC->cache_size_in_bytes);
249 "adap %d cache good, bytecount == cache size = %d\n",
250 pC->adap_idx, byte_count);
252 pC->init = (u16)cached;
259 static short find_control(u16 control_index,
260 struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI)
262 if (!control_cache_alloc_check(p_cache)) {
263 HPI_DEBUG_LOG(VERBOSE,
264 "control_cache_alloc_check() failed %d\n",
269 *pI = p_cache->p_info[control_index];
271 HPI_DEBUG_LOG(VERBOSE, "Uncached Control %d\n",
275 HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n",
276 (*pI)->control_type);
281 /* allow unified treatment of several string fields within struct */
282 #define HPICMN_PAD_OFS_AND_SIZE(m) {\
283 offsetof(struct hpi_control_cache_pad, m), \
284 sizeof(((struct hpi_control_cache_pad *)(NULL))->m) }
286 struct pad_ofs_size {
288 unsigned int field_size;
291 static struct pad_ofs_size pad_desc[] = {
292 HPICMN_PAD_OFS_AND_SIZE(c_channel), /* HPI_PAD_CHANNEL_NAME */
293 HPICMN_PAD_OFS_AND_SIZE(c_artist), /* HPI_PAD_ARTIST */
294 HPICMN_PAD_OFS_AND_SIZE(c_title), /* HPI_PAD_TITLE */
295 HPICMN_PAD_OFS_AND_SIZE(c_comment), /* HPI_PAD_COMMENT */
298 /** CheckControlCache checks the cache and fills the struct hpi_response
299 * accordingly. It returns one if a cache hit occurred, zero otherwise.
301 short hpi_check_control_cache(struct hpi_control_cache *p_cache,
302 struct hpi_message *phm, struct hpi_response *phr)
305 struct hpi_control_cache_info *pI;
306 struct hpi_control_cache_single *pC;
307 struct hpi_control_cache_pad *p_pad;
309 if (!find_control(phm->obj_index, p_cache, &pI)) {
310 HPI_DEBUG_LOG(VERBOSE,
311 "HPICMN find_control() failed for adap %d\n",
318 /* pC is the default cached control strucure. May be cast to
319 something else in the following switch statement.
321 pC = (struct hpi_control_cache_single *)pI;
322 p_pad = (struct hpi_control_cache_pad *)pI;
324 switch (pI->control_type) {
326 case HPI_CONTROL_METER:
327 if (phm->u.c.attribute == HPI_METER_PEAK) {
328 phr->u.c.an_log_value[0] = pC->u.meter.an_log_peak[0];
329 phr->u.c.an_log_value[1] = pC->u.meter.an_log_peak[1];
330 } else if (phm->u.c.attribute == HPI_METER_RMS) {
331 if (pC->u.meter.an_logRMS[0] ==
332 HPI_CACHE_INVALID_SHORT) {
334 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
335 phr->u.c.an_log_value[0] = HPI_METER_MINIMUM;
336 phr->u.c.an_log_value[1] = HPI_METER_MINIMUM;
338 phr->u.c.an_log_value[0] =
339 pC->u.meter.an_logRMS[0];
340 phr->u.c.an_log_value[1] =
341 pC->u.meter.an_logRMS[1];
346 case HPI_CONTROL_VOLUME:
347 if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
348 phr->u.c.an_log_value[0] = pC->u.vol.an_log[0];
349 phr->u.c.an_log_value[1] = pC->u.vol.an_log[1];
353 case HPI_CONTROL_MULTIPLEXER:
354 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
355 phr->u.c.param1 = pC->u.mux.source_node_type;
356 phr->u.c.param2 = pC->u.mux.source_node_index;
361 case HPI_CONTROL_CHANNEL_MODE:
362 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
363 phr->u.c.param1 = pC->u.mode.mode;
367 case HPI_CONTROL_LEVEL:
368 if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
369 phr->u.c.an_log_value[0] = pC->u.level.an_log[0];
370 phr->u.c.an_log_value[1] = pC->u.level.an_log[1];
374 case HPI_CONTROL_TUNER:
375 if (phm->u.c.attribute == HPI_TUNER_FREQ)
376 phr->u.c.param1 = pC->u.tuner.freq_ink_hz;
377 else if (phm->u.c.attribute == HPI_TUNER_BAND)
378 phr->u.c.param1 = pC->u.tuner.band;
379 else if (phm->u.c.attribute == HPI_TUNER_LEVEL_AVG)
380 if (pC->u.tuner.s_level_avg ==
381 HPI_CACHE_INVALID_SHORT) {
382 phr->u.cu.tuner.s_level = 0;
384 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
386 phr->u.cu.tuner.s_level =
387 pC->u.tuner.s_level_avg;
391 case HPI_CONTROL_AESEBU_RECEIVER:
392 if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS)
393 phr->u.c.param1 = pC->u.aes3rx.error_status;
394 else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
395 phr->u.c.param1 = pC->u.aes3rx.format;
399 case HPI_CONTROL_AESEBU_TRANSMITTER:
400 if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
401 phr->u.c.param1 = pC->u.aes3tx.format;
405 case HPI_CONTROL_TONEDETECTOR:
406 if (phm->u.c.attribute == HPI_TONEDETECTOR_STATE)
407 phr->u.c.param1 = pC->u.tone.state;
411 case HPI_CONTROL_SILENCEDETECTOR:
412 if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) {
413 phr->u.c.param1 = pC->u.silence.state;
417 case HPI_CONTROL_MICROPHONE:
418 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
419 phr->u.c.param1 = pC->u.microphone.phantom_state;
423 case HPI_CONTROL_SAMPLECLOCK:
424 if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
425 phr->u.c.param1 = pC->u.clk.source;
426 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) {
427 if (pC->u.clk.source_index ==
428 HPI_CACHE_INVALID_UINT16) {
431 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
433 phr->u.c.param1 = pC->u.clk.source_index;
434 } else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
435 phr->u.c.param1 = pC->u.clk.sample_rate;
439 case HPI_CONTROL_PAD:{
440 struct hpi_control_cache_pad *p_pad;
441 p_pad = (struct hpi_control_cache_pad *)pI;
443 if (!(p_pad->field_valid_flags & (1 <<
444 HPI_CTL_ATTR_INDEX(phm->u.c.
447 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
451 if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID)
452 phr->u.c.param1 = p_pad->pI;
453 else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE)
454 phr->u.c.param1 = p_pad->pTY;
457 HPI_CTL_ATTR_INDEX(phm->u.c.
459 unsigned int offset = phm->u.c.param1;
460 unsigned int pad_string_len, field_size;
464 if (index > ARRAY_SIZE(pad_desc) - 1) {
466 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
472 pad_desc[index].offset;
473 field_size = pad_desc[index].field_size;
474 /* Ensure null terminator */
475 pad_string[field_size - 1] = 0;
477 pad_string_len = strlen(pad_string) + 1;
479 if (offset > pad_string_len) {
481 HPI_ERROR_INVALID_CONTROL_VALUE;
485 tocopy = pad_string_len - offset;
486 if (tocopy > sizeof(phr->u.cu.chars8.sz_data))
487 tocopy = sizeof(phr->u.cu.chars8.
490 memcpy(phr->u.cu.chars8.sz_data,
491 &pad_string[offset], tocopy);
493 phr->u.cu.chars8.remaining_chars =
494 pad_string_len - offset - tocopy;
503 HPI_DEBUG_LOG(VERBOSE, "%s Adap %d, Ctl %d, Type %d, Attr %d\n",
504 found ? "Cached" : "Uncached", phm->adapter_index,
505 pI->control_index, pI->control_type, phm->u.c.attribute);
509 sizeof(struct hpi_response_header) +
510 sizeof(struct hpi_control_res);
515 /** Updates the cache with Set values.
517 Only update if no error.
518 Volume and Level return the limited values in the response, so use these
519 Multiplexer does so use sent values
521 void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache,
522 struct hpi_message *phm, struct hpi_response *phr)
524 struct hpi_control_cache_single *pC;
525 struct hpi_control_cache_info *pI;
530 if (!find_control(phm->obj_index, p_cache, &pI)) {
531 HPI_DEBUG_LOG(VERBOSE,
532 "HPICMN find_control() failed for adap %d\n",
537 /* pC is the default cached control strucure.
538 May be cast to something else in the following switch statement.
540 pC = (struct hpi_control_cache_single *)pI;
542 switch (pI->control_type) {
543 case HPI_CONTROL_VOLUME:
544 if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
545 pC->u.vol.an_log[0] = phr->u.c.an_log_value[0];
546 pC->u.vol.an_log[1] = phr->u.c.an_log_value[1];
549 case HPI_CONTROL_MULTIPLEXER:
550 /* mux does not return its setting on Set command. */
551 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
552 pC->u.mux.source_node_type = (u16)phm->u.c.param1;
553 pC->u.mux.source_node_index = (u16)phm->u.c.param2;
556 case HPI_CONTROL_CHANNEL_MODE:
557 /* mode does not return its setting on Set command. */
558 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
559 pC->u.mode.mode = (u16)phm->u.c.param1;
561 case HPI_CONTROL_LEVEL:
562 if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
563 pC->u.vol.an_log[0] = phr->u.c.an_log_value[0];
564 pC->u.vol.an_log[1] = phr->u.c.an_log_value[1];
567 case HPI_CONTROL_MICROPHONE:
568 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
569 pC->u.microphone.phantom_state = (u16)phm->u.c.param1;
571 case HPI_CONTROL_AESEBU_TRANSMITTER:
572 if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
573 pC->u.aes3tx.format = phm->u.c.param1;
575 case HPI_CONTROL_AESEBU_RECEIVER:
576 if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
577 pC->u.aes3rx.format = phm->u.c.param1;
579 case HPI_CONTROL_SAMPLECLOCK:
580 if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
581 pC->u.clk.source = (u16)phm->u.c.param1;
582 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX)
583 pC->u.clk.source_index = (u16)phm->u.c.param1;
584 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
585 pC->u.clk.sample_rate = phm->u.c.param1;
592 struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count,
593 const u32 size_in_bytes, u8 *p_dsp_control_buffer)
595 struct hpi_control_cache *p_cache =
596 kmalloc(sizeof(*p_cache), GFP_KERNEL);
601 kmalloc(sizeof(*p_cache->p_info) * control_count, GFP_KERNEL);
602 if (!p_cache->p_info) {
606 memset(p_cache->p_info, 0, sizeof(*p_cache->p_info) * control_count);
607 p_cache->cache_size_in_bytes = size_in_bytes;
608 p_cache->control_count = control_count;
609 p_cache->p_cache = p_dsp_control_buffer;
614 void hpi_free_control_cache(struct hpi_control_cache *p_cache)
617 kfree(p_cache->p_info);
622 static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
624 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, 0);
626 switch (phm->function) {
627 case HPI_SUBSYS_OPEN:
628 case HPI_SUBSYS_CLOSE:
629 case HPI_SUBSYS_DRIVER_UNLOAD:
631 case HPI_SUBSYS_DRIVER_LOAD:
633 hpios_alistlock_init(&adapters);
635 case HPI_SUBSYS_GET_ADAPTER:
636 subsys_get_adapter(phm, phr);
638 case HPI_SUBSYS_GET_NUM_ADAPTERS:
639 phr->u.s.num_adapters = adapters.gw_num_adapters;
641 case HPI_SUBSYS_CREATE_ADAPTER:
642 case HPI_SUBSYS_DELETE_ADAPTER:
645 phr->error = HPI_ERROR_INVALID_FUNC;
650 void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr)
653 case HPI_TYPE_MESSAGE:
654 switch (phm->object) {
655 case HPI_OBJ_SUBSYSTEM:
656 subsys_message(phm, phr);
662 phr->error = HPI_ERROR_INVALID_TYPE;