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