~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/pci/asihpi/hpicmn.c

Version: ~ [ linux-5.12 ] ~ [ linux-5.11.16 ] ~ [ linux-5.10.32 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.114 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.188 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.231 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.267 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.267 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /******************************************************************************
  2 
  3     AudioScience HPI driver
  4     Copyright (C) 1997-2014  AudioScience Inc. <support@audioscience.com>
  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"
 29 #include "hpimsginit.h"
 30 
 31 #include "hpicmn.h"
 32 
 33 struct 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 
 39 static 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 **/
 46 u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr)
 47 {
 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;
 51         }
 52 
 53         if (phr->object != phm->object) {
 54                 HPI_DEBUG_LOG(ERROR, "header object %d invalid\n",
 55                         phr->object);
 56                 return HPI_ERROR_INVALID_RESPONSE;
 57         }
 58 
 59         if (phr->function != phm->function) {
 60                 HPI_DEBUG_LOG(ERROR, "header function %d invalid\n",
 61                         phr->function);
 62                 return HPI_ERROR_INVALID_RESPONSE;
 63         }
 64 
 65         return 0;
 66 }
 67 
 68 u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
 69 {
 70         u16 retval = 0;
 71         /*HPI_ASSERT(pao->type); */
 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 
 80         if (adapters.adapter[pao->index].type) {
 81                 int a;
 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);
 87                                 pao->index = a;
 88                                 break;
 89                         }
 90                 }
 91                 if (a < 0) {
 92                         retval = HPI_ERROR_DUPLICATE_ADAPTER_NUMBER;
 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 
100 unlock:
101         hpios_alistlock_unlock(&adapters);
102         return retval;
103 }
104 
105 void hpi_delete_adapter(struct hpi_adapter_obj *pao)
106 {
107         if (!pao->type) {
108                 HPI_DEBUG_LOG(ERROR, "removing null adapter?\n");
109                 return;
110         }
111 
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);
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 */
124 struct 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) {
129                 HPI_DEBUG_LOG(VERBOSE, "find_adapter invalid index %d\n",
130                         adapter_index);
131                 return NULL;
132         }
133 
134         pao = &adapters.adapter[adapter_index];
135         if (pao->type != 0) {
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 **/
155 static void wipe_adapter_list(void)
156 {
157         memset(&adapters, 0, sizeof(adapters));
158 }
159 
160 static void subsys_get_adapter(struct hpi_message *phm,
161         struct hpi_response *phr)
162 {
163         int count = phm->obj_index;
164         u16 index = 0;
165 
166         /* find the nCount'th nonzero adapter in array */
167         for (index = 0; index < HPI_MAX_ADAPTERS; index++) {
168                 if (adapters.adapter[index].type) {
169                         if (!count)
170                                 break;
171                         count--;
172                 }
173         }
174 
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;
178         } else {
179                 phr->u.s.adapter_index = 0;
180                 phr->u.s.adapter_type = 0;
181                 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
182         }
183 }
184 
185 static 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;
191 
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",
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 *)
208                                 &p_master_cache[byte_count];
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                         }
217 
218                         if (!info->size_in32bit_words) {
219                                 if (!i) {
220                                         HPI_DEBUG_LOG(INFO,
221                                                 "adap %d cache not ready?\n",
222                                                 pC->adap_idx);
223                                         return 0;
224                                 }
225                                 /* The cache is invalid.
226                                  * Minimum valid entry size is
227                                  * sizeof(struct hpi_control_cache_info)
228                                  */
229                                 HPI_DEBUG_LOG(ERROR,
230                                         "adap %d zero size cache entry %d\n",
231                                         pC->adap_idx, i);
232                                 break;
233                         }
234 
235                         if (info->control_type) {
236                                 pC->p_info[control_index] = info;
237                                 cached++;
238                         } else {        /* dummy cache entry */
239                                 pC->p_info[control_index] = NULL;
240                         }
241 
242                         byte_count += info->size_in32bit_words * 4;
243 
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);
249 
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                          */
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;
259                 }
260 
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);
266                 else
267                         HPI_DEBUG_LOG(DEBUG,
268                                 "adap %d cache good, bytecount == cache size = %d\n",
269                                 pC->adap_idx, byte_count);
270 
271                 pC->init = (u16)cached;
272         }
273         return pC->init;
274 }
275 
276 /** Find a control.
277 */
278 static short find_control(u16 control_index,
279         struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI)
280 {
281         if (!control_cache_alloc_check(p_cache)) {
282                 HPI_DEBUG_LOG(VERBOSE,
283                         "control_cache_alloc_check() failed %d\n",
284                         control_index);
285                 return 0;
286         }
287 
288         *pI = p_cache->p_info[control_index];
289         if (!*pI) {
290                 HPI_DEBUG_LOG(VERBOSE, "Uncached Control %d\n",
291                         control_index);
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 
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 
305 struct pad_ofs_size {
306         unsigned int offset;
307         unsigned int field_size;
308 };
309 
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 */
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  */
320 short hpi_check_control_cache_single(struct hpi_control_cache_single *pC,
321         struct hpi_message *phm, struct hpi_response *phr)
322 {
323         size_t response_size;
324         short found = 1;
325 
326         /* set the default response size */
327         response_size =
328                 sizeof(struct hpi_response_header) +
329                 sizeof(struct hpi_control_res);
330 
331         switch (pC->u.i.control_type) {
332 
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) {
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                         }
350                 } else
351                         found = 0;
352                 break;
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)
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 {
370                         found = 0;
371                 }
372                 break;
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;
377                 } else {
378                         found = 0;
379                 }
380                 break;
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;
384                 else
385                         found = 0;
386                 break;
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];
391                 } else
392                         found = 0;
393                 break;
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;
403                                 phr->error =
404                                         HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
405                         } else
406                                 phr->u.cu.tuner.s_level =
407                                         pC->u.tuner.s_level_avg;
408                 else
409                         found = 0;
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)
415                         phr->u.c.param1 = pC->u.aes3rx.format;
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;
434                 } else
435                         found = 0;
436                 break;
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;
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 ==
448                                 HPI_CACHE_INVALID_UINT16) {
449                                 phr->u.c.param1 = 0;
450                                 phr->error =
451                                         HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
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;
459         case HPI_CONTROL_PAD:{
460                         struct hpi_control_cache_pad *p_pad;
461                         p_pad = (struct hpi_control_cache_pad *)pC;
462 
463                         if (!(p_pad->field_valid_flags & (1 <<
464                                                 HPI_CTL_ATTR_INDEX(phm->u.c.
465                                                         attribute)))) {
466                                 phr->error =
467                                         HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
468                                 break;
469                         }
470 
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;
515                         }
516                 }
517                 break;
518         default:
519                 found = 0;
520                 break;
521         }
522 
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,
526                 phm->u.c.attribute);
527 
528         if (found) {
529                 phr->size = (u16)response_size;
530                 phr->type = HPI_TYPE_RESPONSE;
531                 phr->object = phm->object;
532                 phr->function = phm->function;
533         }
534 
535         return found;
536 }
537 
538 short hpi_check_control_cache(struct hpi_control_cache *p_cache,
539         struct hpi_message *phm, struct hpi_response *phr)
540 {
541         struct hpi_control_cache_info *pI;
542 
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);
547                 return 0;
548         }
549 
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.
559 
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
563 */
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)
566 {
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) {
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;
577                 }
578                 break;
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;
584                 }
585                 break;
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;
590                 break;
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];
595                 }
596                 break;
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;
600                 break;
601         case HPI_CONTROL_AESEBU_TRANSMITTER:
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:
606                 if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
607                         pC->u.aes3rx.format = phm->u.c.param1;
608                 break;
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;
616                 break;
617         default:
618                 break;
619         }
620 }
621 
622 void 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 
646 /** Allocate control cache.
647 
648 \return Cache pointer, or NULL if allocation fails.
649 */
650 struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count,
651         const u32 size_in_bytes, u8 *p_dsp_control_buffer)
652 {
653         struct hpi_control_cache *p_cache =
654                 kmalloc(sizeof(*p_cache), GFP_KERNEL);
655         if (!p_cache)
656                 return NULL;
657 
658         p_cache->p_info =
659                 kcalloc(control_count, sizeof(*p_cache->p_info), GFP_KERNEL);
660         if (!p_cache->p_info) {
661                 kfree(p_cache);
662                 return NULL;
663         }
664 
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;
668         p_cache->init = 0;
669         return p_cache;
670 }
671 
672 void hpi_free_control_cache(struct hpi_control_cache *p_cache)
673 {
674         if (p_cache) {
675                 kfree(p_cache->p_info);
676                 kfree(p_cache);
677         }
678 }
679 
680 static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
681 {
682         hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, 0);
683 
684         switch (phm->function) {
685         case HPI_SUBSYS_OPEN:
686         case HPI_SUBSYS_CLOSE:
687         case HPI_SUBSYS_DRIVER_UNLOAD:
688                 break;
689         case HPI_SUBSYS_DRIVER_LOAD:
690                 wipe_adapter_list();
691                 hpios_alistlock_init(&adapters);
692                 break;
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;
698                 break;
699         case HPI_SUBSYS_CREATE_ADAPTER:
700                 break;
701         default:
702                 phr->error = HPI_ERROR_INVALID_FUNC;
703                 break;
704         }
705 }
706 
707 void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr)
708 {
709         switch (phm->type) {
710         case HPI_TYPE_REQUEST:
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 }
723 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp