ASoC: rt5677: use gpiochip data pointer
[deliverable/linux.git] / sound / pci / asihpi / hpicmn.c
CommitLineData
719f82d3
EB
1/******************************************************************************
2
3 AudioScience HPI driver
c1464a88 4 Copyright (C) 1997-2014 AudioScience Inc. <support@audioscience.com>
719f82d3
EB
5
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;
9
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.
14
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
18
19\file hpicmn.c
20
21 Common functions used by hpixxxx.c modules
22
23(C) Copyright AudioScience Inc. 1998-2003
24*******************************************************************************/
25#define SOURCEFILE_NAME "hpicmn.c"
26
27#include "hpi_internal.h"
28#include "hpidebug.h"
3285ea10
EB
29#include "hpimsginit.h"
30
719f82d3
EB
31#include "hpicmn.h"
32
33struct hpi_adapters_list {
34 struct hpios_spinlock list_lock;
35 struct hpi_adapter_obj adapter[HPI_MAX_ADAPTERS];
36 u16 gw_num_adapters;
37};
38
39static struct hpi_adapters_list adapters;
40
41/**
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
45**/
46u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr)
47{
3285ea10 48 if (phr->type != HPI_TYPE_RESPONSE) {
1528fbb5 49 HPI_DEBUG_LOG(ERROR, "header type %d invalid\n", phr->type);
3285ea10
EB
50 return HPI_ERROR_INVALID_RESPONSE;
51 }
52
53 if (phr->object != phm->object) {
1528fbb5
EB
54 HPI_DEBUG_LOG(ERROR, "header object %d invalid\n",
55 phr->object);
3285ea10
EB
56 return HPI_ERROR_INVALID_RESPONSE;
57 }
719f82d3 58
3285ea10 59 if (phr->function != phm->function) {
938c565a 60 HPI_DEBUG_LOG(ERROR, "header function %d invalid\n",
1528fbb5 61 phr->function);
3285ea10
EB
62 return HPI_ERROR_INVALID_RESPONSE;
63 }
719f82d3 64
3285ea10 65 return 0;
719f82d3
EB
66}
67
68u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
69{
70 u16 retval = 0;
7036b92d 71 /*HPI_ASSERT(pao->type); */
719f82d3
EB
72
73 hpios_alistlock_lock(&adapters);
74
75 if (pao->index >= HPI_MAX_ADAPTERS) {
76 retval = HPI_ERROR_BAD_ADAPTER_NUMBER;
77 goto unlock;
78 }
79
7036b92d 80 if (adapters.adapter[pao->index].type) {
d6f1c1c3
EB
81 int a;
82 for (a = HPI_MAX_ADAPTERS - 1; a >= 0; a--) {
7036b92d 83 if (!adapters.adapter[a].type) {
d6f1c1c3
EB
84 HPI_DEBUG_LOG(WARNING,
85 "ASI%X duplicate index %d moved to %d\n",
7036b92d 86 pao->type, pao->index, a);
d6f1c1c3
EB
87 pao->index = a;
88 break;
89 }
90 }
91 if (a < 0) {
92 retval = HPI_ERROR_DUPLICATE_ADAPTER_NUMBER;
719f82d3
EB
93 goto unlock;
94 }
95 }
96 adapters.adapter[pao->index] = *pao;
97 hpios_dsplock_init(&adapters.adapter[pao->index]);
98 adapters.gw_num_adapters++;
99
100unlock:
3285ea10 101 hpios_alistlock_unlock(&adapters);
719f82d3
EB
102 return retval;
103}
104
105void hpi_delete_adapter(struct hpi_adapter_obj *pao)
106{
7036b92d 107 if (!pao->type) {
3285ea10
EB
108 HPI_DEBUG_LOG(ERROR, "removing null adapter?\n");
109 return;
110 }
719f82d3
EB
111
112 hpios_alistlock_lock(&adapters);
7036b92d 113 if (adapters.adapter[pao->index].type)
3285ea10
EB
114 adapters.gw_num_adapters--;
115 memset(&adapters.adapter[pao->index], 0, sizeof(adapters.adapter[0]));
116 hpios_alistlock_unlock(&adapters);
719f82d3
EB
117}
118
119/**
120* FindAdapter returns a pointer to the struct hpi_adapter_obj with
121* index wAdapterIndex in an HPI_ADAPTERS_LIST structure.
122*
123*/
124struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index)
125{
126 struct hpi_adapter_obj *pao = NULL;
127
128 if (adapter_index >= HPI_MAX_ADAPTERS) {
1528fbb5 129 HPI_DEBUG_LOG(VERBOSE, "find_adapter invalid index %d\n",
719f82d3
EB
130 adapter_index);
131 return NULL;
132 }
133
134 pao = &adapters.adapter[adapter_index];
7036b92d 135 if (pao->type != 0) {
719f82d3
EB
136 /*
137 HPI_DEBUG_LOG(VERBOSE, "Found adapter index %d\n",
138 wAdapterIndex);
139 */
140 return pao;
141 } else {
142 /*
143 HPI_DEBUG_LOG(VERBOSE, "No adapter index %d\n",
144 wAdapterIndex);
145 */
146 return NULL;
147 }
148}
149
150/**
151*
152* wipe an HPI_ADAPTERS_LIST structure.
153*
154**/
3285ea10 155static void wipe_adapter_list(void)
719f82d3
EB
156{
157 memset(&adapters, 0, sizeof(adapters));
158}
159
3285ea10
EB
160static void subsys_get_adapter(struct hpi_message *phm,
161 struct hpi_response *phr)
719f82d3 162{
3285ea10
EB
163 int count = phm->obj_index;
164 u16 index = 0;
719f82d3 165
3285ea10
EB
166 /* find the nCount'th nonzero adapter in array */
167 for (index = 0; index < HPI_MAX_ADAPTERS; index++) {
7036b92d 168 if (adapters.adapter[index].type) {
4704998e 169 if (!count)
3285ea10
EB
170 break;
171 count--;
719f82d3 172 }
719f82d3
EB
173 }
174
3285ea10
EB
175 if (index < HPI_MAX_ADAPTERS) {
176 phr->u.s.adapter_index = adapters.adapter[index].index;
7036b92d 177 phr->u.s.adapter_type = adapters.adapter[index].type;
3285ea10
EB
178 } else {
179 phr->u.s.adapter_index = 0;
2f918a64 180 phr->u.s.adapter_type = 0;
7036b92d 181 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
3285ea10 182 }
719f82d3
EB
183}
184
185static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
186{
187 unsigned int i;
188 int cached = 0;
189 if (!pC)
190 return 0;
719f82d3 191
3285ea10
EB
192 if (pC->init)
193 return pC->init;
194
195 if (!pC->p_cache)
196 return 0;
197
198 if (pC->control_count && pC->cache_size_in_bytes) {
199 char *p_master_cache;
200 unsigned int byte_count = 0;
201
202 p_master_cache = (char *)pC->p_cache;
203 HPI_DEBUG_LOG(DEBUG, "check %d controls\n",
719f82d3
EB
204 pC->control_count);
205 for (i = 0; i < pC->control_count; i++) {
206 struct hpi_control_cache_info *info =
207 (struct hpi_control_cache_info *)
3285ea10 208 &p_master_cache[byte_count];
c1464a88
EB
209 u16 control_index = info->control_index;
210
211 if (control_index >= pC->control_count) {
212 HPI_DEBUG_LOG(INFO,
213 "adap %d control index %d out of range, cache not ready?\n",
214 pC->adap_idx, control_index);
215 return 0;
216 }
3285ea10
EB
217
218 if (!info->size_in32bit_words) {
4704998e 219 if (!i) {
ffdb5787
EB
220 HPI_DEBUG_LOG(INFO,
221 "adap %d cache not ready?\n",
222 pC->adap_idx);
223 return 0;
224 }
1528fbb5
EB
225 /* The cache is invalid.
226 * Minimum valid entry size is
227 * sizeof(struct hpi_control_cache_info)
228 */
3285ea10 229 HPI_DEBUG_LOG(ERROR,
ffdb5787
EB
230 "adap %d zero size cache entry %d\n",
231 pC->adap_idx, i);
3285ea10
EB
232 break;
233 }
719f82d3
EB
234
235 if (info->control_type) {
c1464a88 236 pC->p_info[control_index] = info;
719f82d3 237 cached++;
42258dab 238 } else { /* dummy cache entry */
c1464a88 239 pC->p_info[control_index] = NULL;
42258dab 240 }
719f82d3 241
3285ea10 242 byte_count += info->size_in32bit_words * 4;
719f82d3
EB
243
244 HPI_DEBUG_LOG(VERBOSE,
3285ea10
EB
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);
249
1528fbb5
EB
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
253 */
3285ea10
EB
254 if (byte_count >= pC->cache_size_in_bytes)
255 break;
256 /* have seen last control index */
257 if (info->control_index == pC->control_count - 1)
258 break;
719f82d3 259 }
3285ea10
EB
260
261 if (byte_count != pC->cache_size_in_bytes)
262 HPI_DEBUG_LOG(WARNING,
1528fbb5 263 "adap %d bytecount %d != cache size %d\n",
ffdb5787 264 pC->adap_idx, byte_count,
3285ea10
EB
265 pC->cache_size_in_bytes);
266 else
267 HPI_DEBUG_LOG(DEBUG,
1528fbb5 268 "adap %d cache good, bytecount == cache size = %d\n",
ffdb5787 269 pC->adap_idx, byte_count);
3285ea10 270
1528fbb5 271 pC->init = (u16)cached;
719f82d3
EB
272 }
273 return pC->init;
274}
275
276/** Find a control.
277*/
3285ea10
EB
278static short find_control(u16 control_index,
279 struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI)
719f82d3 280{
719f82d3
EB
281 if (!control_cache_alloc_check(p_cache)) {
282 HPI_DEBUG_LOG(VERBOSE,
3285ea10
EB
283 "control_cache_alloc_check() failed %d\n",
284 control_index);
719f82d3
EB
285 return 0;
286 }
287
3285ea10 288 *pI = p_cache->p_info[control_index];
719f82d3 289 if (!*pI) {
3285ea10
EB
290 HPI_DEBUG_LOG(VERBOSE, "Uncached Control %d\n",
291 control_index);
719f82d3
EB
292 return 0;
293 } else {
294 HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n",
295 (*pI)->control_type);
296 }
297 return 1;
298}
299
719f82d3
EB
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) }
304
305struct pad_ofs_size {
306 unsigned int offset;
307 unsigned int field_size;
308};
309
42258dab 310static const struct pad_ofs_size pad_desc[] = {
719f82d3
EB
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 */
315};
316
317/** CheckControlCache checks the cache and fills the struct hpi_response
318 * accordingly. It returns one if a cache hit occurred, zero otherwise.
319 */
c1464a88 320short hpi_check_control_cache_single(struct hpi_control_cache_single *pC,
719f82d3
EB
321 struct hpi_message *phm, struct hpi_response *phr)
322{
3d0591ee 323 size_t response_size;
c1464a88 324 short found = 1;
719f82d3 325
c6c2c9ab
EB
326 /* set the default response size */
327 response_size =
328 sizeof(struct hpi_response_header) +
329 sizeof(struct hpi_control_res);
330
c1464a88 331 switch (pC->u.i.control_type) {
719f82d3
EB
332
333 case HPI_CONTROL_METER:
334 if (phm->u.c.attribute == HPI_METER_PEAK) {
3285ea10
EB
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];
719f82d3 337 } else if (phm->u.c.attribute == HPI_METER_RMS) {
3285ea10
EB
338 if (pC->u.meter.an_logRMS[0] ==
339 HPI_CACHE_INVALID_SHORT) {
340 phr->error =
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;
344 } else {
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];
349 }
719f82d3
EB
350 } else
351 found = 0;
352 break;
353 case HPI_CONTROL_VOLUME:
354 if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
3285ea10
EB
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];
fc3a3990
EB
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)
360 phr->u.c.param1 =
361 HPI_BITMASK_ALL_CHANNELS;
362 else
363 phr->u.c.param1 = 0;
364 } else {
365 phr->error =
366 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
367 phr->u.c.param1 = 0;
368 }
369 } else {
719f82d3 370 found = 0;
fc3a3990 371 }
719f82d3
EB
372 break;
373 case HPI_CONTROL_MULTIPLEXER:
374 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
3285ea10
EB
375 phr->u.c.param1 = pC->u.mux.source_node_type;
376 phr->u.c.param2 = pC->u.mux.source_node_index;
719f82d3
EB
377 } else {
378 found = 0;
379 }
380 break;
381 case HPI_CONTROL_CHANNEL_MODE:
382 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
3285ea10 383 phr->u.c.param1 = pC->u.mode.mode;
719f82d3
EB
384 else
385 found = 0;
386 break;
387 case HPI_CONTROL_LEVEL:
388 if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
3285ea10
EB
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];
719f82d3
EB
391 } else
392 found = 0;
393 break;
394 case HPI_CONTROL_TUNER:
3ee317fe 395 if (phm->u.c.attribute == HPI_TUNER_FREQ)
3285ea10 396 phr->u.c.param1 = pC->u.tuner.freq_ink_hz;
3ee317fe 397 else if (phm->u.c.attribute == HPI_TUNER_BAND)
3285ea10
EB
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;
36ed8bdd
EB
403 phr->error =
404 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
405 } else
3285ea10
EB
406 phr->u.cu.tuner.s_level =
407 pC->u.tuner.s_level_avg;
3ee317fe
EB
408 else
409 found = 0;
719f82d3
EB
410 break;
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)
3285ea10 415 phr->u.c.param1 = pC->u.aes3rx.format;
719f82d3
EB
416 else
417 found = 0;
418 break;
419 case HPI_CONTROL_AESEBU_TRANSMITTER:
420 if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
421 phr->u.c.param1 = pC->u.aes3tx.format;
422 else
423 found = 0;
424 break;
425 case HPI_CONTROL_TONEDETECTOR:
426 if (phm->u.c.attribute == HPI_TONEDETECTOR_STATE)
427 phr->u.c.param1 = pC->u.tone.state;
428 else
429 found = 0;
430 break;
431 case HPI_CONTROL_SILENCEDETECTOR:
432 if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) {
433 phr->u.c.param1 = pC->u.silence.state;
719f82d3
EB
434 } else
435 found = 0;
436 break;
437 case HPI_CONTROL_MICROPHONE:
438 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
3285ea10 439 phr->u.c.param1 = pC->u.microphone.phantom_state;
719f82d3
EB
440 else
441 found = 0;
442 break;
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 ==
3285ea10 448 HPI_CACHE_INVALID_UINT16) {
719f82d3 449 phr->u.c.param1 = 0;
36ed8bdd
EB
450 phr->error =
451 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
719f82d3
EB
452 } else
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;
456 else
457 found = 0;
458 break;
3285ea10
EB
459 case HPI_CONTROL_PAD:{
460 struct hpi_control_cache_pad *p_pad;
c1464a88 461 p_pad = (struct hpi_control_cache_pad *)pC;
719f82d3 462
3285ea10
EB
463 if (!(p_pad->field_valid_flags & (1 <<
464 HPI_CTL_ATTR_INDEX(phm->u.c.
465 attribute)))) {
719f82d3
EB
466 phr->error =
467 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
468 break;
469 }
470
3285ea10
EB
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;
475 else {
476 unsigned int index =
477 HPI_CTL_ATTR_INDEX(phm->u.c.
478 attribute) - 1;
479 unsigned int offset = phm->u.c.param1;
480 unsigned int pad_string_len, field_size;
481 char *pad_string;
482 unsigned int tocopy;
483
484 if (index > ARRAY_SIZE(pad_desc) - 1) {
485 phr->error =
486 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
487 break;
488 }
489
490 pad_string =
491 ((char *)p_pad) +
492 pad_desc[index].offset;
493 field_size = pad_desc[index].field_size;
494 /* Ensure null terminator */
495 pad_string[field_size - 1] = 0;
496
497 pad_string_len = strlen(pad_string) + 1;
498
499 if (offset > pad_string_len) {
500 phr->error =
501 HPI_ERROR_INVALID_CONTROL_VALUE;
502 break;
503 }
504
505 tocopy = pad_string_len - offset;
506 if (tocopy > sizeof(phr->u.cu.chars8.sz_data))
507 tocopy = sizeof(phr->u.cu.chars8.
508 sz_data);
509
510 memcpy(phr->u.cu.chars8.sz_data,
511 &pad_string[offset], tocopy);
512
513 phr->u.cu.chars8.remaining_chars =
514 pad_string_len - offset - tocopy;
719f82d3 515 }
719f82d3
EB
516 }
517 break;
518 default:
519 found = 0;
520 break;
521 }
522
3285ea10
EB
523 HPI_DEBUG_LOG(VERBOSE, "%s Adap %d, Ctl %d, Type %d, Attr %d\n",
524 found ? "Cached" : "Uncached", phm->adapter_index,
c1464a88
EB
525 pC->u.i.control_index, pC->u.i.control_type,
526 phm->u.c.attribute);
719f82d3 527
8637bc94 528 if (found) {
3d0591ee 529 phr->size = (u16)response_size;
8637bc94
EB
530 phr->type = HPI_TYPE_RESPONSE;
531 phr->object = phm->object;
532 phr->function = phm->function;
533 }
719f82d3
EB
534
535 return found;
536}
537
c1464a88 538short hpi_check_control_cache(struct hpi_control_cache *p_cache,
719f82d3
EB
539 struct hpi_message *phm, struct hpi_response *phr)
540{
719f82d3
EB
541 struct hpi_control_cache_info *pI;
542
3285ea10
EB
543 if (!find_control(phm->obj_index, p_cache, &pI)) {
544 HPI_DEBUG_LOG(VERBOSE,
545 "HPICMN find_control() failed for adap %d\n",
546 phm->adapter_index);
c1464a88 547 return 0;
3285ea10 548 }
719f82d3 549
c1464a88
EB
550 phr->error = 0;
551 phr->specific_error = 0;
552 phr->version = 0;
553
554 return hpi_check_control_cache_single((struct hpi_control_cache_single
555 *)pI, phm, phr);
556}
557
558/** Updates the cache with Set values.
719f82d3 559
c1464a88
EB
560Only update if no error.
561Volume and Level return the limited values in the response, so use these
562Multiplexer does so use sent values
563*/
564void hpi_cmn_control_cache_sync_to_msg_single(struct hpi_control_cache_single
565 *pC, struct hpi_message *phm, struct hpi_response *phr)
566{
567 switch (pC->u.i.control_type) {
719f82d3
EB
568 case HPI_CONTROL_VOLUME:
569 if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
3285ea10
EB
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];
fc3a3990
EB
572 } else if (phm->u.c.attribute == HPI_VOLUME_MUTE) {
573 if (phm->u.c.param1)
574 pC->u.vol.flags |= HPI_VOLUME_FLAG_MUTED;
575 else
576 pC->u.vol.flags &= ~HPI_VOLUME_FLAG_MUTED;
719f82d3
EB
577 }
578 break;
579 case HPI_CONTROL_MULTIPLEXER:
580 /* mux does not return its setting on Set command. */
719f82d3 581 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
3285ea10
EB
582 pC->u.mux.source_node_type = (u16)phm->u.c.param1;
583 pC->u.mux.source_node_index = (u16)phm->u.c.param2;
719f82d3
EB
584 }
585 break;
586 case HPI_CONTROL_CHANNEL_MODE:
587 /* mode does not return its setting on Set command. */
719f82d3 588 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
3285ea10 589 pC->u.mode.mode = (u16)phm->u.c.param1;
719f82d3
EB
590 break;
591 case HPI_CONTROL_LEVEL:
592 if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
3285ea10
EB
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];
719f82d3
EB
595 }
596 break;
597 case HPI_CONTROL_MICROPHONE:
598 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
3285ea10 599 pC->u.microphone.phantom_state = (u16)phm->u.c.param1;
719f82d3
EB
600 break;
601 case HPI_CONTROL_AESEBU_TRANSMITTER:
719f82d3
EB
602 if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
603 pC->u.aes3tx.format = phm->u.c.param1;
604 break;
605 case HPI_CONTROL_AESEBU_RECEIVER:
719f82d3 606 if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
3285ea10 607 pC->u.aes3rx.format = phm->u.c.param1;
719f82d3
EB
608 break;
609 case HPI_CONTROL_SAMPLECLOCK:
719f82d3
EB
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;
616 break;
617 default:
618 break;
619 }
620}
621
c1464a88
EB
622void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache,
623 struct hpi_message *phm, struct hpi_response *phr)
624{
625 struct hpi_control_cache_single *pC;
626 struct hpi_control_cache_info *pI;
627
628 if (phr->error)
629 return;
630
631 if (!find_control(phm->obj_index, p_cache, &pI)) {
632 HPI_DEBUG_LOG(VERBOSE,
633 "HPICMN find_control() failed for adap %d\n",
634 phm->adapter_index);
635 return;
636 }
637
638 /* pC is the default cached control strucure.
639 May be cast to something else in the following switch statement.
640 */
641 pC = (struct hpi_control_cache_single *)pI;
642
643 hpi_cmn_control_cache_sync_to_msg_single(pC, phm, phr);
644}
645
42258dab
EB
646/** Allocate control cache.
647
648\return Cache pointer, or NULL if allocation fails.
649*/
4704998e
EB
650struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count,
651 const u32 size_in_bytes, u8 *p_dsp_control_buffer)
719f82d3
EB
652{
653 struct hpi_control_cache *p_cache =
654 kmalloc(sizeof(*p_cache), GFP_KERNEL);
fd0977d0
JJ
655 if (!p_cache)
656 return NULL;
4704998e 657
c1464a88
EB
658 p_cache->p_info =
659 kcalloc(control_count, sizeof(*p_cache->p_info), GFP_KERNEL);
fd0977d0
JJ
660 if (!p_cache->p_info) {
661 kfree(p_cache);
662 return NULL;
663 }
c1464a88 664
719f82d3 665 p_cache->cache_size_in_bytes = size_in_bytes;
4704998e
EB
666 p_cache->control_count = control_count;
667 p_cache->p_cache = p_dsp_control_buffer;
719f82d3 668 p_cache->init = 0;
719f82d3
EB
669 return p_cache;
670}
671
672void hpi_free_control_cache(struct hpi_control_cache *p_cache)
673{
3285ea10 674 if (p_cache) {
719f82d3 675 kfree(p_cache->p_info);
719f82d3
EB
676 kfree(p_cache);
677 }
678}
679
680static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
681{
3285ea10 682 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, 0);
719f82d3
EB
683
684 switch (phm->function) {
685 case HPI_SUBSYS_OPEN:
686 case HPI_SUBSYS_CLOSE:
687 case HPI_SUBSYS_DRIVER_UNLOAD:
719f82d3
EB
688 break;
689 case HPI_SUBSYS_DRIVER_LOAD:
690 wipe_adapter_list();
691 hpios_alistlock_init(&adapters);
719f82d3 692 break;
3285ea10
EB
693 case HPI_SUBSYS_GET_ADAPTER:
694 subsys_get_adapter(phm, phr);
695 break;
696 case HPI_SUBSYS_GET_NUM_ADAPTERS:
697 phr->u.s.num_adapters = adapters.gw_num_adapters;
719f82d3
EB
698 break;
699 case HPI_SUBSYS_CREATE_ADAPTER:
719f82d3
EB
700 break;
701 default:
702 phr->error = HPI_ERROR_INVALID_FUNC;
703 break;
704 }
705}
706
707void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr)
708{
709 switch (phm->type) {
82b5774f 710 case HPI_TYPE_REQUEST:
719f82d3
EB
711 switch (phm->object) {
712 case HPI_OBJ_SUBSYSTEM:
713 subsys_message(phm, phr);
714 break;
715 }
716 break;
717
718 default:
719 phr->error = HPI_ERROR_INVALID_TYPE;
720 break;
721 }
722}
This page took 0.271996 seconds and 5 git commands to generate.